Java反射教程


Java反射(Reflection)教程

1. 反射简介

Java反射机制允许程序在运行时动态获取类的信息,并可访问类的构造方法、字段、方法等。反射广泛应用于框架开发、依赖注入、序列化以及动态代理。

核心特点

  • 可以动态加载类
  • 可以访问类的私有成员
  • 可以在运行时实例化对象、调用方法

2. 获取Class对象

反射的第一步是获取目标类的Class对象:

1
2
3
4
5
6
7
8
9
// 方式1: 通过类名.class
Class<String> clazz1 = String.class;

// 方式2: 通过对象实例
String str = "hello";
Class<?> clazz2 = str.getClass();

// 方式3: 通过Class.forName()
Class<?> clazz3 = Class.forName("java.lang.String");

3. 获取构造方法并实例化对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.lang.reflect.Constructor;

class Person {
private String name;
public Person(String name) {
this.name = name;
}
public void sayHello() {
System.out.println("Hello, " + name);
}
}

public class ReflectionExample {
public static void main(String[] args) throws Exception {
Class<Person> clazz = Person.class;
Constructor<Person> constructor = clazz.getConstructor(String.class);
Person p = constructor.newInstance("张三");
p.sayHello(); // 输出: Hello, 张三
}
}

4. 访问字段(Field)

可以通过反射访问类的字段,包括私有字段:

1
2
3
4
5
6
import java.lang.reflect.Field;

Field field = clazz.getDeclaredField("name");
field.setAccessible(true); // 设置可访问私有字段
field.set(p, "李四");
System.out.println(field.get(p)); // 输出: 李四

5. 调用方法(Method)

通过反射获取方法并调用:

1
2
3
4
import java.lang.reflect.Method;

Method method = clazz.getMethod("sayHello");
method.invoke(p); // 输出: Hello, 李四

对于私有方法,使用getDeclaredMethod并设置setAccessible(true)


6. 获取类的元数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 获取所有方法
Method[] methods = clazz.getMethods();
for(Method m : methods) {
System.out.println(m.getName());
}

// 获取所有字段
Field[] fields = clazz.getDeclaredFields();
for(Field f : fields) {
System.out.println(f.getName());
}

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

7. 注意事项

  • 性能开销:反射会绕过编译期检查,运行效率较低,不适合高频调用场景。
  • 安全性:反射可访问私有成员,需注意安全风险。
  • 泛型信息:反射获取的类信息是原始类型,泛型信息会被擦除。

8. 总结

Java反射提供了强大的运行时动态操作能力,使程序在运行时可以分析类结构、动态调用方法和操作对象。它是许多Java框架(如Spring、MyBatis)底层实现的基础,但在使用时需注意性能和安全性。