反射机制—java基础核心部分
java中的反射可以可以在程序运行时动态的获取类的各种详细信息,包括成员属性,成员方法,构造方法.从而操作类或者的属性和方法.是框架的灵魂所在
1.获取对象的Class类
JVM将类的字节码文件通过类加载器加载进内存然后就会生成一个对应的Class对象.获取到Class对象之后就可以进行各种操作了.有三种方式可以获取到Class对象.
- 通过Class.forName()方法
- 通过 类.class成员来获取
- 通过 对象.getClass()来获取
// method 1
Class objectClass1 = Class.forName("java.lang.Object");
// method 2
Class<Object> objectClass2 = Object.class;
//method 3
Class<? extends Object> objectClass3 = new Object().getClass();
而且需要注意的是:不管通过什么方法获取同一个类的Class对象,获取的都是同一个对象
System.out.println(objectClass1 == objectClass2);//true
System.out.println(objectClass1 == objectClass3);//true
System.out.println(objectClass2 == objectClass3);//true
2.获取类的成员对象
一共有四种方法可以获取类的成员对象
- getField():只能获取public属性
- getFields():获取所有public对象的对象数组
- getDeclaredField():可以获取任意属性,但是只能对public进行操作
- getDeclaredFields():可以获取任意属性,但是只能对public进行操作
Person person = new Person(1, 2, 3, 4);
Class<? extends Person> personClass = person.getClass();
//只能获取public属性
Field variable1 = personClass.getField("variable1");
//获取所有public对象的对象数组
Field[] fields = personClass.getFields();
//通过set方法设置某个Person对象的具体值
variable1.set(person, 1);
//通过get可以获取某个Person对象的具体值
Integer value1 = (Integer) variable1.get(person);
//可以获取任意属性,但是只能对public进行操作
Field variable4 = personClass.getDeclaredField("variable4");
Field[] declaredFields = personClass.getDeclaredFields();
//通过setAccessible方法突破限制,暴力反射
variable4.setAccessible(true);
Integer value4 = (Integer) variable4.get(person);
3.获取类的成员方法
与获取类的成员对象相似,一共有四种方法可以获取类的成员方法对象
- getMethod():获取public成员方法对象
- getMethods():获取public成员方法对象数组
- getDeclaredMethod():可以获取任意成员方法对象,但只能对public进行操作
- getDeclaredMethods():可以获取任意成员方法对象数组,但只能对public进行操作
Person person = new Person(1, 2, 3, 4);
Class<? extends Person> personClass = person.getClass();
Method[] methods = personClass.getMethods();
//通过方法的名字和参数的Class类列表来获取方法对象
Method setVariable1 = personClass.getMethod("setVariable1", Integer.class);
//通过invoke方法来调用该方法.参数是调用该方法的对象,以及方法的参数列表.结果就是返回值
Void result1= (Void) setVariable1.invoke(person, 2);
Method[] declaredMethods = personClass.getDeclaredMethods();
Method privateMethod = personClass.getDeclaredMethod("privateMethod", String.class);
//同样可以通过setAccessible来突破限制,暴力反射
privateMethod.setAccessible(true);
String result2= (String) privateMethod.invoke(person, "MarkLau");
4.获取类的构造方法对象
有四种方法可以获取到类的构造方法对象,太相似了就不多介绍了
- getConstructor();
- getConstructors();
- getDeclaredConstructor();
- getDeclaredConstructors();
Person person = new Person();
Class<? extends Person> personClass = person.getClass();
//由于所有的构造方法名字都相同所以不需要方法名,只需要通过参数就可以进行判断
Constructor<? extends Person> constructor = personClass.getConstructor(Integer.class, Integer.class, Integer.class, Integer.class);
//调用newInstance方法,再将参数传入就可以生成一个新的对象
Person person1 = constructor.newInstance(1, 2, 3, 4);
//通过Class对象来创建的对象只能使用无参构造
Person person2 = personClass.newInstance();