Java利用反射创建实体类、设置实体类属性、调用实体类的方法(含传参)、
创始人
2025-05-28 03:57:07

1. 问题描述

这里我们使用 java 的反射特性,完成几个简单的例子,用于学习总结。

2. 准备工作

创建一个类,含有属性和方法,用于接下来我们通过反射创建它的对象,调用它的方法,修改它的属性。

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"));}
}

3. 使用 java 原生的方法

3.1 构造方法

  1. 使用字符串(类的路径)创建类,再通过newInstance创建对象。
    // 1.1 通过字符串获得类,并创建对象(不穿参数),再调用两个public方法
    Class clazz1 = (Class) Class.forName("cn.smileyan.reflex.entity.Student");
    Student student1 = clazz1.getConstructor().newInstance();
    student1.say();
    student1.say("reflex1");
    
  2. 通过字符串构建类,并创建对象(传参),再调用两个public方法
    // 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");
    
  3. 通过类.class创建实体(推荐)
    // 1.3 通过类创建实体
    Class clazz3 = Student.class;
    Student student3 = clazz3.getConstructor(Integer.class, String.class).newInstance(3, "Jack");
    student3.say();
    student3.say("reflex3");
    

3.2 通过反射调用类的对象的方法

  1. 通过字符串不创建实体类而是通过方法名调用方法
    // 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();
    
  2. 通过字符串不创建实体类而是通过方法名调用方法,并传入参数。
    // 1.5 通过反射调用对象的某个方法
    Student student5 = new Student();
    Class clazz5 = Student.class;
    Method method5 = clazz5.getDeclaredMethod("say", String.class);
    method5.invoke(student5, "reflex5");
    System.out.println();
    

4. 使用 ReflectASM 反射方法

添加依赖:

        com.esotericsoftwarereflectasm1.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);

5. 总结

反射还会有更多的应用场景,这里只是简单的记录一下,今后收集到更多案例再进行补充。

Smileyan
2023.03.14 23:23

相关内容

热门资讯

“人工智能+招投标”营造公共资... (来源:内蒙古日报)转自:内蒙古日报□本报记者  许敬  内蒙古能源集团包头喜桂图发电有限公司的会议...
平谷区最新或2023(历届)兵...   依据《中华人民共和国兵役法》和《北京市征兵工作条例》以及有关法律法规的规定,本区最新或2023(...
平谷区召开最新或2023(历届... 10月25日,平谷区召开冬季征兵动员工作会,动员部署冬季征兵工作。区委副书记、区长、区征兵工作领导小...
昌平区最新或2023(历届)冬...   10月24日上午,昌平区冬季征兵工作动员大会召开,总结全区征兵工作,部署度工作任务。   区领导...
大兴区召开最新或2023(历届... 为进一步贯彻落实全市冬季征兵工作会议精神,总结征兵工作,部署征兵任务,10月25日,我区召开冬季征兵...