1.什么是反射?
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取信息以及动态调用对象的方法的功能称为 java 语言的反射机制。
2. 反射实操
案例一:
获取对象使用Class.forName()
创建对象使用 clazz.getConstructor(),然后初始化对象使用 construoctor.newInstance()
调用方法使用 clazz.getMethod(获取指定方法名),使用method.invoke(obj)获取方法返回的结果
(1)获取Class对象:
Class<?> clazz = Class.forName("java.lang.String");
(2)创建对象:
Constructor<?> constructor = clazz.getConstructor(String.class);
Object obj = constructor.newInstance("Hello World");
(3)调用方法:
Method method = clazz.getMethod("toUpperCase");
String result = (String) method.invoke(obj);
System.out.println(result); //输出结果:HELLO WORLD
示例代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
// 添加 getter 和 setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public class Main {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("Person");
// 获取带有 String 和 Integer 参数的构造函数
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
// 使用正确的参数创建对象
Object person = constructor.newInstance("shenghao", 21);
// 获取 getName 方法
Method method = clazz.getMethod("getName");
// 调用方法并获取结果
String result = (String) method.invoke(person);
System.out.println(result); // 应该输出: shenghao
}
}
案例二:
(1)获取Class对象
Class<?> clazz = Person.class;
(2)创建对象(还是使用Constructor创建)
Constructor<?> constructor = clazz.getConstructor();
Person person = (Person)constructor. newInstance();
或则
Constructor<?> constructor = clazz.getConstructor(String.class,Integer.class);
Person person = (Person)constructor. newInstance("shenghao",21);
(3)获取字段
Field nameField = clazz.getDeclaredField("name");
Field ageField = clazz.getField("age");
(4)设置字段
因为name和age是私有字段(使用private修饰),所以使用setAccessible(true),运行字段可访问
nameField.setAccessible(true);
ageField.setAccessible(true);
开始设置字段信息
nameField.set(person,"Bob");
ageField.set(person,25);
(5)获取字段值并打印
System.out.println(nameField.get(person)); // 输出Bob
System.out.println(ageField.get(person)); // 输出25
示例代码:
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// 定义 Person 类
class Person {
private String name;
private Integer age;
public Person(){
}
// 带参数的构造函数
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
// getter 和 setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
// 主类
public class Main {
public static void main(String[] args) throws Exception {
// 获取 Person 类的 Class 对象
Class<?> clazz = Person.class;
// 获取并使用无参数的构造函数创建 Person 对象
Constructor<?> constructor = clazz.getConstructor();
Person person = (Person) constructor.newInstance();
// 获取私有字段
Field nameField = clazz.getDeclaredField("name");
Field ageField = clazz.getDeclaredField("age");
// 设置字段可访问(跳过 Java 的访问控制检查)
nameField.setAccessible(true);
ageField.setAccessible(true);
// 设置字段值
nameField.set(person, "Bob");
ageField.set(person, 25);
// 获取字段值并打印
System.out.println(nameField.get(person)); // 输出: Bob
System.out.println(ageField.get(person)); // 输出: 25
}
}