1. 获取 `Class` 对象
在 Java 中,有三种常见的方式来获取 `Class` 对象:
java
// 方式一:使用 Class.forName() 方法
try {
Class<?> clazz1 = Class.forName("java.util.ArrayList");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 方式二:使用类名.class 语法
Class<?> clazz2 = java.util.ArrayList.class;
// 方式三:使用对象的 getClass() 方法
java.util.ArrayList list = new java.util.ArrayList();
Class<?> clazz3 = list.getClass();
2. 创建对象
通过反射创建对象有两种主要方式:使用无参构造函数和使用有参构造函数。
使用无参构造函数
java
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Person {
public Person() {
System.out.println("Person 无参构造函数被调用");
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
Class<?> clazz = Person.class;
// 创建对象
Person person = (Person) clazz.getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
使用有参构造函数
java
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person 有参构造函数被调用,姓名: " + name + ", 年龄: " + age);
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
Class<?> clazz = Person.class;
// 获取有参构造函数
Constructor<?> constructor = clazz.getDeclaredConstructor(String.class, int.class);
// 创建对象
Person person = (Person) constructor.newInstance("Alice", 25);
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
3. 调用方法
通过反射可以调用类的方法,包括无参方法和有参方法。
调用无参方法
java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Calculator {
public int add() {
return 1 + 2;
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
Calculator calculator = new Calculator();
Class<?> clazz = calculator.getClass();
// 获取方法
Method method = clazz.getMethod("add");
// 调用方法
int result = (int) method.invoke(calculator);
System.out.println("调用 add 方法的结果: " + result);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
调用有参方法
java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Calculator {
public int add(int a, int b) {
return a + b;
}
}
public class ReflectionExample {
public static void main(String[] args) {
try {
Calculator calculator = new Calculator();
Class<?> clazz = calculator.getClass();
// 获取方法
Method method = clazz.getMethod("add", int.class, int.class);
// 调用方法
int result = (int) method.invoke(calculator, 3, 4);
System.out.println("调用 add 方法的结果: " + result);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
4. 访问字段
通过反射可以访问类的字段,包括获取字段的值和设置字段的值。
java
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
class Person {
public String name = "Bob";
}
public class ReflectionExample {
public static void main(String[] args) {
try {
Person person = new Person();
Class<?> clazz = person.getClass();
// 获取字段
Field field = clazz.getField("name");
// 获取字段的值
String name = (String) field.get(person);
System.out.println("原来的姓名: " + name);
// 设置字段的值
field.set(person, "Charlie");
name = (String) field.get(person);
System.out.println("修改后的姓名: " + name);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
}
注意事项
- 反射机制会带来一定的性能开销,因为它涉及到运行时的动态解析和调用。
- 使用反射时需要处理可能抛出的异常,如 `NoSuchMethodException`、`IllegalAccessException`、`InvocationTargetException` 等。
- 反射可以访问和修改类的私有成员,但这可能会破坏类的封装性,应谨慎使用。
通过上述示例,你可以了解 Java 反射的基本使用方法,包括获取 `Class` 对象、创建对象、调用方法和访问字段。反射机制为 Java 程序提供了强大的动态性和灵活性,但也需要谨慎使用。