允许程序在运行时访问和操作类的属性和方法。这使得 Java 在某些情况下更加灵活,能够动态地加载类、创建对象以及调用方法。
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// 获取 Class 对象
Class<?> clazz = Class.forName("com.example.MyClass");
// 创建实例
Constructor<?> constructor = clazz.getConstructor();
Object instance = constructor.newInstance();
// 访问字段
Field field = clazz.getDeclaredField("myField");
field.setAccessible(true); // 访问私有字段
field.set(instance, "Hello Reflection");
// 调用方法
Method method = clazz.getDeclaredMethod("myMethod");
method.setAccessible(true); // 访问私有方法
method.invoke(instance);
}
}
1. 获取 Class
对象
Class.forName(String className)
:通过类名获取对应的Class
对象。MyClass.class
:直接通过类名获取Class
对象。object.getClass()
:通过对象获取其对应的Class
对象。
package com.example;
public class MyClass {
private String message;
public MyClass() {
this.message = "Hello, World!";
}
public void displayMessage() {
System.out.println(message);
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
// 1. 使用 Class.forName
Class<?> clazz1 = Class.forName("com.example.MyClass");
System.out.println("Class Name from forName: " + clazz1.getName());
// 2. 使用 MyClass.class
Class<MyClass> clazz2 = MyClass.class;
System.out.println("Class Name from class literal: " + clazz2.getName());
// 3. 使用 object.getClass()
MyClass myObject = new MyClass();
Class<?> clazz3 = myObject.getClass();
System.out.println("Class Name from instance: " + clazz3.getName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//输出结果
Class Name from forName: com.example.MyClass
Class Name from class literal: com.example.MyClass
Class Name from instance: com.example.MyClass
2. 创建对象(调用构造器)
newInstance()
:通过无参构造器创建类的实例(已被弃用,推荐使用Constructor
)。Constructor
类:getConstructor(Class<?>... parameterTypes)
:获取公共构造器。getDeclaredConstructor(Class<?>... parameterTypes)
:获取声明的构造器(包括私有构造器)。newInstance(Object... initargs)
:通过构造器创建实例。
package com.example;
public class Person {
private String name;
private int age;
// 无参构造器
public Person() {
this.name = "Unknown";
this.age = 0;
}
// 带参数的构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 私有构造器
private Person(String name) {
this.name = name;
this.age = 25; // 默认年龄
}
public void display() {
System.out.println("Name: " + name + ", Age: " + age);
}
public static Person createWithName(String name) throws Exception {
Constructor<?> privateConstructor =
Person.class.getDeclaredConstructor(String.class);
privateConstructor.setAccessible(true); // 允许访问私有构造器
return (Person) privateConstructor.newInstance(name);
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
// 1. 使用 newInstance()(已被弃用)
Class<?> clazz = Class.forName("com.example.Person");
Person person1 = (Person) clazz.newInstance();
person1.display(); // 输出: Name: Unknown, Age: 0
// 2. 获取公共构造器
Constructor<?> publicConstructor = clazz.getConstructor(String.class, int.class);
Person person2 = (Person) publicConstructor.newInstance("Alice", 30);
person2.display(); // 输出: Name: Alice, Age: 30
// 3. 通过私有构造器创建实例
Person person3 = Person.createWithName("Bob");
person3.display(); // 输出: Name: Bob, Age: 25
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. 访问字段
getField(String name)
:获取公共字段。- getFields() :获得所有公共字段,返回Field[]数组。
getDeclaredField(String name)
:获取声明的字段(包括私有字段)。- getDeclaredFields():获得声明的所有字段(包括私有字段),返回Field[]数组。
Field
类的方法:get(Object obj)
:获取字段的值。set(Object obj, Object value)
:设置字段的值。setAccessible(true)
:允许访问私有字段。
package com.example;
public class Car {
public String brand;
private int year;
public Car(String brand, int year) {
this.brand = brand;
this.year = year;
}
public void display() {
System.out.println("Brand: " + brand + ", Year: " + year);
}
}
import java.lang.reflect.Field;
public class ReflectionExample {
public static void main(String[] args) {
try {
// 创建 Car 实例
Car car = new Car("Toyota", 2020);
// 1. 获取公共字段
Field brandField = Car.class.getField("brand");
String brandValue = (String) brandField.get(car);
System.out.println("Brand: " + brandValue); // 输出: Brand: Toyota
// 2. 获取私有字段
Field yearField = Car.class.getDeclaredField("year");
yearField.setAccessible(true); // 允许访问私有字段
int yearValue = (int) yearField.get(car);
System.out.println("Year: " + yearValue); // 输出: Year: 2020
// 3. 修改公共字段
brandField.set(car, "Honda");
car.display(); // 输出: Brand: Honda, Year: 2020
// 4. 修改私有字段
yearField.set(car, 2022);
car.display(); // 输出: Brand: Honda, Year: 2022
} catch (Exception e) {
e.printStackTrace();
}
}
}
//输出
Brand: Toyota
Year: 2020
Brand: Honda, Year: 2020
Brand: Honda, Year: 2022
4. 调用方法
getMethod(String name, Class<?>... parameterTypes)
:获取公共方法。- getMethods():获取所有公共方法,返回
Method[]
数组。 getDeclaredMethod(String name, Class<?>... parameterTypes)
:获取声明的方法(包括私有方法)。getDeclaredMethod():获取所有声明的方法(包括私有方法)。返回Method[]
数组。Method
类的方法:invoke(Object obj, Object... args)
:调用方法。setAccessible(true)
:允许访问私有方法。
package com.example;
public class Calculator {
public int add(int a, int b) {
return a + b;
}
private int subtract(int a, int b) {
return a - b;
}
public void displayResult(int result) {
System.out.println("Result: " + result);
}
}
import java.lang.reflect.Method;
public class ReflectionExample {
public static void main(String[] args) {
try {
// 创建 Calculator 实例
Calculator calculator = new Calculator();
// 1. 获取所有公共方法
Method[] publicMethods = Calculator.class.getMethods();
System.out.println("Public Methods:");
for (Method method : publicMethods) {
System.out.println(method.getName());
}
// 2. 获取所有声明的方法(包括私有方法)
Method[] allMethods = Calculator.class.getDeclaredMethods();
System.out.println("\nAll Declared Methods:");
for (Method method : allMethods) {
System.out.println(method.getName());
}
// 3. 调用公共方法
Method addMethod = Calculator.class.getMethod("add", int.class, int.class);
int sum = (int) addMethod.invoke(calculator, 5, 3);
System.out.println("\nSum: " + sum); // 输出: Sum: 8
// 4. 调用私有方法
Method subtractMethod = Calculator.class.getDeclaredMethod("subtract", int.class, int.class);
subtractMethod.setAccessible(true); // 允许访问私有方法
int difference = (int) subtractMethod.invoke(calculator, 5, 3);
System.out.println("Difference: " + difference); // 输出: Difference: 2
// 5. 调用公共方法并打印结果
Method displayMethod = Calculator.class.getMethod("displayResult", int.class);
displayMethod.invoke(calculator, sum); // 输出: Result: 8
} catch (Exception e) {
e.printStackTrace();
}
}
}
//结果
Public Methods:
add
displayResult
All Declared Methods:
add
subtract
displayResult
Sum: 8
Difference: 2
Result: 8