了解:大部分框架实现的原理就是利用的反射。
Java反射原理
1.将Java文件保存到本地硬盘
2.编译Java文件,生成.class文件
3.使用Java虚拟机(JVM)将字节码文件加载到内存
4.字节码文件在内存中使用Class类表示
5.使用反射的时候,首先获取到Class类,就可以得到class文件里的所有内容,包含属性、构造方法、普通方法
6.属性通过Filed类表示
7.构造方法通过Constructor表示
8.普通方法通过Method表示
得到Class类的三种方法
以Person.java为例
package reflect;
public class Person {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public Person(String name, String age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
}
//第一种方法
Class class1 = Person.class
//第二种方法
Class class2 = new Person().getClass();
//第三种方法
Class class3 = Class.forName("Person.java的路径");
具体操作属性、构造器、方法
注意:当方法或属性用静态修饰,某些方法用到对象时,用null表示。如:m.invoke(null, "wangmazi");
使用反射操作属性
private static void field()
throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
// 使用反射操作属性(变量)
Class class1 = Class.forName("reflect.Person");
// 得到所有的属性
// class1.getDeclaredFields();
// 得到对象
Person p = (Person) class1.newInstance();
// 得到指定的属性
Field f = class1.getDeclaredField("name");
// 设置方法允许操作私有属性
f.setAccessible(true);
// 赋值
f.set(p, "zhangsan");
// 获取值(Person中设置属性为私有,需要设置一个方法setAccessible(true))
System.out.println(f.get(p));
}
使用反射操作构造器
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, InstantiationException,
IllegalAccessException, InvocationTargetException {
Class class2 = Class.forName("reflect.Person");
// 得到所有的构造方法
// class2.getConstructor();
// 得到指定的构造方法
Constructor c = class2.getConstructor(String.class, String.class);
// 得到对象
Person p = (Person) c.newInstance("lisi", "100");
System.out.println(p.getName() + p.getAge());
}
使用反射操作方法
private static void method() throws ClassNotFoundException, InstantiationException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException {
Class class3 = Class.forName("reflect.Person");
// 得到对象
Person p = (Person) class3.newInstance();
// 获取所有普通方法
class3.getDeclaredMethods();
// 获取指定参数普通方法
Method m = class3.getDeclaredMethod("setName", String.class);
m.invoke(p, "wangmazi");
System.out.println(p.getName());
}