Java的反射应用(Method和Class)

记录:473

场景:使用java.lang.reflect.Method和java.lang.Class类,根据Java反射原理实现使用指定字符串类名和方法名称,调用对应对象和对应方法。

版本:JDK 1.8。

1.使用Java反射调用指定类的指定方法

(1)参数说明

String className, 字符串类型,需反射的类的全路径。

String methodName, 字符串类型,需反射的类的方法名称。

Object params,对象类型,反射调用方法的输入参数。

Object,返回值,反射调用方法的输出参数。

(2)代码实现

public class ReflectApplyUtils {
    /**
     * 根据类名称和方法名称执行指定类的指定方法
     * 获取public方法
     * Method[] method01 = clasz.getMethods();
     * 获取private方法
     * Method[] method02 = clasz.getDeclaredMethods();
     */
    public static Object executeByName(String className, String methodName, Object params) {
        Object result = null;
        try {
            //1.根据类名称获取该类对应的Class对象
            Class<?> clasz = Class.forName(className);
            //2.根据方法名称获取改方法对应的Method对象
            Method method = null;
            for (Method var1 : clasz.getMethods()) {
                if (StringUtils.equals(var1.getName(), methodName)) {
                    method = var1;
                    break;
                }
            }
            //3.执行具体方法
            if (method != null) {
                //获取方法的Modifier值,在根据Modifier定义的常量可以判断方式是哪种类型
                int var2 = method.getModifiers();
                if (Modifier.isPublic(var2) && Modifier.isStatic(var2)) {
                    result = method.invoke(clasz, params);
                } else if (Modifier.isPublic(var2) && !Modifier.isStatic(var2)) {
                    result = method.invoke(clasz.newInstance(), params);
                } else {
                    throw new Exception("提供的方法名称: " + methodName + ",不是public类型,无权限执行.");
                }
            } else {
                throw new Exception("根据方法名称: " + methodName + ",无法找到对应Method,请检查输入的方法名称是否正确.");
            }
        } catch (Exception e) {
            result = e;
        }
        return result;
    }
}

2.一个普通Java类

本示例中,将使用反射调用此类。

/**
 * java.lang.StringBuffer,线程安全(A thread-safe)
 * java.lang.StringBuilder,非线程安全
 */
public class HostSportGames {
    public static String tableTennisContest(TeamDto team) {
        StringBuffer sb = new StringBuffer();
        sb.append("执行业务: ").append(team.getTeamName())
                .append(team.getGroup()).append("参加")
                .append(team.getEvent()).append(",运动员:");
        StringBuffer finalSb = sb;
        team.getAthlete().forEach((item) -> {
            finalSb.append(item).append(",");
        });
        sb = sb.replace(sb.length() - 1, sb.length(), ".");
        System.out.println(sb);
        return "乒乓球比赛成功";
    }
    public String swimmingContest(TeamDto team) {

        StringBuilder sb = new StringBuilder();
        sb.append("执行业务: ").append(team.getTeamName())
                .append(team.getGroup()).append("参加")
                .append(team.getEvent()).append(",运动员:");
        StringBuilder finalSb = sb;
        team.getAthlete().forEach((item) -> {
            finalSb.append(item).append(",");
        });
        sb = sb.replace(sb.length() - 1, sb.length(), ".");
        System.out.println(sb);
        return "游泳比赛成功";
    }
    private Object footballContest(TeamDto team) {
        System.out.println("暂无此赛事.");
        return "暂无此比赛";
    }
}

3.Java反射调用指定类的指定方法

(1)代码实现

public class ApplyReflect {
    public static void main(String[] args) {
        //1.数据准备
        TeamDto team01 = TeamDto.builder()
                .teamName("中国乒乓球队")
                .group("男子组")
                .event("男单决赛")
                .athlete(Arrays.asList("ZhangS", "ZhaoL"))
                .build();
        TeamDto team02 = TeamDto.builder()
                .teamName("中国游泳队")
                .group("女子组")
                .event("200米决赛")
                .athlete(Arrays.asList("ZhangJ", "ZhaoX"))
                .build();
        List<Object> task01 = Arrays.asList(
                "com.hub.example.p11.reflect.work.HostSportGames",
                "tableTennisContest", team01
        );
        List<Object> task02 = Arrays.asList(
                "com.hub.example.p11.reflect.work.HostSportGames",
                "swimmingContest", team02
        );
        List<List<Object>> taskList = Arrays.asList(task01, task02);
        //2.执行业务
        for (List<Object> taskItem : taskList) {
            try{
                System.out.println("*******************************");
                String className = (String) taskItem.get(0);
                String methodName = (String) taskItem.get(1);
                TeamDto params = (TeamDto) taskItem.get(2);
                Object executeResult = null;
                System.out.println("执行" + className + "的" + methodName + "方法.");
                System.out.println("输入参数: " + params.toString());
                executeResult = ReflectApplyUtils.executeByName(className, methodName, params);
                System.out.println("输出结果: " + executeResult);
            }catch (Exception e){
                System.out.println("执行异常.");
                e.printStackTrace();
            }
        }
        System.out.println("*******************************");
    }
}

(2)输出日志

*******************************
执行com.hub.example.p11.reflect.work.HostSportGames的tableTennisContest方法.
输入参数: TeamDto(teamName=中国乒乓球队, group=男子组, event=男单决赛, athlete=[ZhangS, ZhaoL])
执行业务: 中国乒乓球队男子组参加男单决赛,运动员:ZhangS,ZhaoL.
输出结果: 乒乓球比赛成功
*******************************
执行com.hub.example.p11.reflect.work.HostSportGames的swimmingContest方法.
输入参数: TeamDto(teamName=中国游泳队, group=女子组, event=200米决赛, athlete=[ZhangJ, ZhaoX])
执行业务: 中国游泳队女子组参加200米决赛,运动员:ZhangJ,ZhaoX.
输出结果: 游泳比赛成功
*******************************

4.辅助实体类

(1)说明

在实体类中使用注解@Data等来自lombok-1.18.24.jar。

(2)代码

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class TeamDto implements Serializable {
    //球队名称
    private String teamName;
    //组别:男子组/女子组/混合组
    private String group;
    //比赛项目名称
    private String event;
    //团队成员
    private List<String> athlete;
}

以上,感谢。

2023年9月13日

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值