Java反射是Java语言的一大特性,它允许程序在运行时获取自身的信息,并且可以操作类或对象的内部属性。通过反射,我们可以在运行时动态地创建对象并调用其属性和方法,这在编译期是未知的。
概念
Java的反射机制是指在运行时刻,对于任何一个类,都能够知道它的所有属性和方法;对任意一个对象,都能够调用它的任意方法和属性。这种动态获取信息以及动态调用方法的功能就是Java的反射机制。Java通过
java.lang.Class
类实现反射机制。
功能
如下:
- 在运行时获取任意一个对象所属的类。
- 在运行时构造任意一个类的对象。
- 在运行时获取任意一个类所具有的成员变量和方法。
- 在运行时调用任意一个类对象的方法。
- 生成动态代理
获取Class对象的方式
1.
Class.forName( 类名)
:通过类的完全限定名字符串获取
2.
Class
:通过类的完全限定名字符串获取
优点
可以让代码更加灵活,为各种框架提供开箱即用的功能提供了便利。例如Spring、MyBatis等框架都使用了反射机制。
缺点
增加了安全问题,比如可以无视泛型参数的安全检查(泛型参数的安全检查发生在编译时)。另外,反射的性能也要稍差点,但对于框架来说实际影响不大。
实例:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// 定义一个简单的类
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// 创建Person对象
Person person = new Person("John");
// 获取Class对象
Class<?> personClass = person.getClass();
// 通过反射调用getName方法
Method getNameMethod = personClass.getMethod("getName");
String name = (String) getNameMethod.invoke(person);
System.out.println("Name: " + name);
// 通过反射调用setName方法
Method setNameMethod = personClass.getMethod("setName", String.class);
setNameMethod.invoke(person, "Jane");
// 再次调用getName方法验证
name = (String) getNameMethod.invoke(person);
System.out.println("New Name: " + name);
// 通过反射访问私有字段
Field nameField = personClass.getDeclaredField("name");
// 设置可访问私有字段
nameField.setAccessible(true);
String privateName = (String) nameField.get(person);
System.out.println("Private Name: " + privateName);
}
}