Reflection 被视为动态语言的关键,反射机制允许程序在执行期借助于 Reflection
API 取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
反射类:java.lang.Class 是反射的源头,下面以 Java 程序运行过程来说明清楚:
我们写代码新建的一个类,通过编译(javac.exe)生成了字节码文件(.class),再用 java.exe 加载该字节码文件到内存(使用的是 JVM 的类装载器)之后,内存缓存中的这一块区域就是这个运行时类所对应的 Class 类的实例,因为这个过程对于每个类的加载来说只有一次,故每个运行时类对应的 Class 类对象都是唯一的。
Java 反射机制提供的功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的成员变量和方法
- 生成动态代理
简单示例:
public class TestReflection {
public static void main(String[] args) throws Exception {
// 通过"类名.class"创建 Class 类(运行时类)的对象
Class<Person> clazz = Person.class;
// 1.创建 clazz 对应的运行时类 Person 的对象并赋给 Person 类对象的引用 p
Person p = clazz.newInstance();
// 2.通过反射,调用运行时类的属性
Field f1 = clazz.getField("age");// 调 public 修饰的属性并赋给 Field 类对象的引用 f1
f1.set(p, 16);
Field f2 = clazz.getDeclaredField("name");// 调非 public 修饰的属性并赋给 Field
// 类对象的引用 f2
f2.setAccessible(true);
f2.set(p, "chen");
System.out.println(p);// Person [age=16, name=chen]
// 3.通过反射,调用运行时类的
Method m1 = clazz.getMethod("custom");
m1.invoke(p);// custom method
Method m2 = clazz.getMethod("custom", String.class);
m2.invoke(p, "arg");// custom method arg
// 说明唯一性
System.out.println(clazz == new Person().getClass());// true
}
}
class Person {
public int age;
private String name;
public Person() {
super();
}
public Person(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person [age=" + age + ", name=" + name + "]";
}
public void custom() {
System.out.println("custom method");
}
public void custom(String s) {
System.out.println("custom method " + s);
}
}
时间: 2024-10-25 00:35:12