这里我们使用 java 的反射特性,完成几个简单的例子,用于学习总结。
创建一个类,含有属性和方法,用于接下来我们通过反射创建它的对象,调用它的方法,修改它的属性。
package cn.smileyan.reflex.entity;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Map;/*** Student 类 用于测试* @author Smileyan*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {private Integer age = 0;private String name = "Tom";public void say(String msg) {System.out.printf("%s %d %s\n", name, age, msg);}public void say() {System.out.printf("%s %d\n", name, age);}private void secret() {System.out.printf("%s %d 私有方法\n", name, age);}public void walk(String way, Integer distance) {System.out.printf("%s %d %s %d\n", name, age, way, distance);}public void walk(Map params) {walk(params.get("way").toString(), (Integer) params.get("distance"));}
}
// 1.1 通过字符串获得类,并创建对象(不穿参数),再调用两个public方法
Class clazz1 = (Class) Class.forName("cn.smileyan.reflex.entity.Student");
Student student1 = clazz1.getConstructor().newInstance();
student1.say();
student1.say("reflex1");
// 1.2 通过字符串构建类,并创建对象(传参),再调用两个public方法
Class clazz2 = (Class) Class.forName("cn.smileyan.reflex.entity.Student");
Student student2 = clazz2.getConstructor(Integer.class, String.class).newInstance(2, "Jerry");
student2.say();
student2.say("reflex2");
// 1.3 通过类创建实体
Class clazz3 = Student.class;
Student student3 = clazz3.getConstructor(Integer.class, String.class).newInstance(3, "Jack");
student3.say();
student3.say("reflex3");
// 1.4 通过字符串不创建实体类而是通过方法名调用方法
Class> clazz4 = Class.forName("cn.smileyan.reflex.entity.Student");
Method method4 = clazz4.getDeclaredMethod("say");
System.out.println("方法名:" + method4.getName() + " 方法返回类型" + method4.getReturnType());
System.out.println();
// 1.5 通过反射调用对象的某个方法
Student student5 = new Student();
Class clazz5 = Student.class;
Method method5 = clazz5.getDeclaredMethod("say", String.class);
method5.invoke(student5, "reflex5");
System.out.println();
添加依赖:
com.esotericsoftware reflectasm 1.11.9
// 1. 创建对象
ConstructorAccess constructor1 = ConstructorAccess.get(Student.class);
Student student1 = constructor1.newInstance();
student1.say();
System.out.println();// 2. 调用方法
Student student2 = new Student();
MethodAccess methodAccess1 = MethodAccess.get(Student.class);
methodAccess1.invoke(student2, "setName", "Awesome McLovin");
methodAccess1.invoke(student2, "say");
System.out.println();
其他的地方相差不大。
注意
: 两种方法中均需要注意,如果掉用 private 方法,或者访问 private 属性,需要设置
method.setAccessible(true);
反射还会有更多的应用场景,这里只是简单的记录一下,今后收集到更多案例再进行补充。
Smileyan
2023.03.14 23:23