Java 反射的基本概念和操作

反射 : 没有反射就没有Java的任何框架
    1.核心操作:Object    
        public final native Class<?> getClass()
        Class : 反射的核心类,描述其他类的类结构
    2.Class 类的三中实例化方式(每个类的Class对象有且仅有一个,由JVM在类加载时创建)
        a.对象.getClass();
        b.类.class();  
        c.Class的静态方法 : Class.forName(String className); (传参需要包含包名)

                 Class<?> cls=Stu.getClass();
		 
		 Class<?>cls2=Student.class;
		 
		 Class<?>cls3=Class.forName("com.bit.javse.HomeWork.Student");


    3.利用class对象反射创建类的对象
     public T newInstance()
        throws InstantiationException, IllegalAccessException

Student Stu2=(Student) cls.newInstance();


    4.反射与类操作
    (1).取得父类信息
        a.取得包名称
        b.取得其父类的Class对象
        c.取得父接口
        cls.getPackage();
        cls.getSuperclass();
        cls.getInterfaces();//返回值为一个数组

		 System.out.println(cls.getSuperclass());
		 System.out.println(cls.getPackageName());
		 Class<?>[]cls2=cls.getInterfaces();
		 for(Class<?>cls3:cls2) {
			 System.out.println(cls3.getName());
		 }


    (2).反射调用构造
        a.Class提供的newInstance()默认调用的类中的无参构造
        b.Class提供的取得构造方法cls.getConstructor();可以传参数,调用类的有参构造  只能取得修饰符为public的构造方法。

		 Constructor<?>ctr=cls.getConstructor(String.class,String.class,int.class);
		 Student Stu2=(Student) ctr.newInstance("andy","XUST",21);


        c.Class提供的取得构造方法数组 cls.getConstructors(); 只能取得修饰符为public的构造方法。

		 Constructor<?>[]constructors=cls.getConstructors();
		 for (Constructor<?> constructor : constructors) {
			System.out.println(constructor);//遍历打印构造名字,打印出来只有public 修饰的构造方法
		}


        d. cls.getDeclaredConstructor(parameterTypes);可以取得protected,缺省(可以直接使用),private方法,private方法不可以直接使用

		 Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		 ctr.setAccessible(true);//当构造方法私有时,必须得改变权限,才可以使用
		 Student Stu2=(Student) ctr.newInstance("andy");


        f. cls.getDeclaredConstructors();可以取得protected,缺省(可以直接使用),private方法,private方法不可以直接使用

		Constructor<?>[] ctrs = cls.getDeclaredConstructors();
		for (Constructor<?> constructor : ctrs) {
			System.out.println(constructor);//可以取得所有的方法
		}


            cons.setAccessible(true);破坏封装后可以使用
    (3).反射调用普通方法
        a.取得所有普通方法
            getMethods(); 返回包括父类的所有public方法

		Method []methods=cls.getMethods();
		for (Method method : methods) {
			System.out.println(method);
		}


           getDeclaredMethods();返回本类的所有方法(包括static),与修饰符无关。和constructor的有区别--->私有方法同样需要先.setAccessible(true);

		Method []methods=cls.getDeclaredMethods();
		for (Method method2 : methods) {
			System.out.println(method2);//打印本类的所有方法
		}


        b.取得指定方法
            getMethod(方法名,方法参数);

		Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		ctr.setAccessible(true);
		Student Stu2=(Student) ctr.newInstance("andy");
		Method method=cls.getMethod("toString");
		System.out.println(method.invoke(Stu2));


            getDeclaredMethod(方法名,方法参数);

		Class<?> cls = Stu.getClass();
		Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		ctr.setAccessible(true);
		Student Stu2=(Student) ctr.newInstance("andy");
		Method method=cls.getDeclaredMethod("protectedMethod");
		method.invoke(Stu2);
		Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		ctr.setAccessible(true);
		Student Stu2=(Student) ctr.newInstance("andy");
		Method method=cls.getDeclaredMethod("privateMethod");//私有方法需要设置权限再使用
		method.setAccessible(true);
		method.invoke(Stu2);


        调用方法:public Object invoke(类的实例化对象,参数)
    (4).反射调用类中属性
        Field.getType();取得类型
        a.取得类中所有属性
            getFields(属性名);//返回包括父类的所有public属性

		Field[] field=cls.getFields();
		for (Field field2 : field) {
			System.out.println(field2);
		}


            getDeclaredFields(属性名);返回本类的所有属性--->但是私有属性不可以读取和操作,通过.setAccessible(true);可以读取和操作属性

		Field[] field=cls.getDeclaredFields();
		for (Field field2 : field) {
			System.out.println(field2);
		}


        b.取得类中指定属性
            getField(属性名);

		Class<?> cls = Stu.getClass();
		Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		ctr.setAccessible(true);
		Student Stu2=(Student) ctr.newInstance("andy");
		Field field=cls.getField("name");
		System.out.println(field.get(Stu2));


            getDeclaredField(属性名);但是私有属性可以get到Field文件,但不可以读取和操作,通过.setAccessible(true);可以读取和操作属性

		Class<?> cls = Stu.getClass();
		Constructor<?>ctr=cls.getDeclaredConstructor(String.class);
		ctr.setAccessible(true);
		Student Stu2=(Student) ctr.newInstance("andy");
		Field field=cls.getDeclaredField("classid");
		field.setAccessible(true);
		field.set(Stu2, 25);
		System.out.println(field.get(Stu2));


    设置属性内容:set(具体实例化对象,属性值);
    取得属性内容:get(具体实例化对象);
    (5).动态设置封装
    动态设置封装性(一次性,设置后只在本次进程有效)
    .setAccessible();

操作反射使用到的类

class Person implements Comparable<Person> {
	public String name;
	private int age;

	public Person() {

	}

	public Person(String name) {
		this.name = name;
	}

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	protected void fatherprotectedMethod() {
		System.out.println("father protected method");
	}
	public String toString() {
		return "name: " + this.name + "    age: " + age + "  ";
	}

	@Override
	public int compareTo(Person o) {
		if (this.age > o.age) {
			return 1;
		} else if (this.age < o.age) {
			return -1;
		} else {
			return this.name.compareTo(o.name);
		}
	}

}
@SuppressWarnings("unused")
class Student extends Person {
	public String school;
	protected int id;
	private int classid;
	String sex;
	public Student() {

	}

	private Student(String name) {
		this.name = name;
	}

	public Student(String name, String school, int age) {
		super(name, age);
		this.school = school;
	}

	public String toString() {
		return super.toString() + "    school: " + this.school + " ";
	}
	
	public void publicMethod() {
		System.out.println("public method");
	}
	protected void protectedMethod() {
		System.out.println("protected method");
	}
	private void privateMethod() {
		System.out.println("private method");
	}
	void defaultMethod() {
		System.out.println("default method");
	}
	
}

猜你喜欢

转载自blog.csdn.net/weixin_41891854/article/details/81571052