Skip to content

什么是反射?

反射是 Java 提供的一种在运行时检查和操作类、接口、对象、方法和字段的能力。它允许程序在运行时可以动态获取类的信息并调用类的方法、访问或修改字段等,即使这些成员是私有的。

主要用途

  • 动态加载类:运行时加载类,不需要在编译时知道类的名称。
  • 访问私有成员:反射可以访问私有字段和方法。
  • 实现框架:很多框架(如spring等)广泛使用反射实现动态功能。
  • 测试:可用于测试私有方法。

通过反射获取类信息

java
Class<?> clazz = String.class;

// 获取类名
System.out.println("类名: " + clazz.getName());
System.out.println("简单类名: " + clazz.getSimpleName());

// 获取包信息
Package pkg = clazz.getPackage();
System.out.println("包名: " + pkg.getName());

// 获取父类
Class<?> superClass = clazz.getSuperclass();

// 获取实现的接口
Class<?>[] interfaces = clazz.getInterfaces();

// 获取所有方法
Method[] methods = clazz.getDeclaredMethods();

// 获取所有字段
Field[] fields = clazz.getDeclaredFields();

// 获取所有构造器
Constructor<?>[] constructors = clazz.getDeclaredConstructors();

// 获取访问修饰符
int modifiers = clazz.getModifiers();
System.out.println("是否为public: " + Modifier.isPublic(modifiers));

通过反射获取 Class 对象

java
// 方式1:通过类名.class
Class<String> stringClass = String.class;

// 方式2:通过对象.getClass()
String str = "Hello";
Class<?> strClass = str.getClass();

// 方式3:通过Class.forName()
try {
    Class<?> clazz = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

通过反射创建对象实例

java
// 使用无参构造器
//获取类的class对象
Class<?> clazz = Class.forName("com.example.Person");
//使用newInstance()创建对象
Object obj1 = clazz.newInstance(); // 已过时,推荐下面的方式

// 使用有参构造器
//使用getConstructor()创建对象
Constructor<?> constructor = clazz.getConstructor(String.class, int.class);
Object obj2 = constructor.newInstance("张三", 25);

通过反射访问和修改字段

java
class Person {
    private String name;
    public int age;
    
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 获取并操作字段
Class<?> clazz = Person.class;
Object person = clazz.getConstructor(String.class, int.class)
                     .newInstance("李四", 30);

// 获取公共字段
Field ageField = clazz.getField("age");
System.out.println("Age: " + ageField.get(person)); // 30
ageField.set(person, 31); // 修改age为31

// 获取私有字段(需要设置可访问性)
Field nameField = clazz.getDeclaredField("name");
nameField.setAccessible(true); // 绕过访问控制
System.out.println("Name: " + nameField.get(person)); // 李四

通过反射调用方法

java
class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    
    private int multiply(int a, int b) {
        return a * b;
    }
}

// 调用公共方法
Class<?> clazz = Calculator.class;
Object calculator = clazz.newInstance();

Method addMethod = clazz.getMethod("add", int.class, int.class);
Object result = addMethod.invoke(calculator, 10, 20);
System.out.println("10 + 20 = " + result); // 30

// 调用私有方法
Method multiplyMethod = clazz.getDeclaredMethod("multiply", int.class, int.class);
multiplyMethod.setAccessible(true);
Object multiplyResult = multiplyMethod.invoke(calculator, 10, 20);
System.out.println("10 * 20 = " + multiplyResult); // 200

通过反射获取注解信息

通过反射,可以读取类,字段,方法上的注解信息。getAnnotations()。

Released under the MIT License.