用案例来展示Java反射机制的应用

2021-07-20 15:52:29 浏览数 (3)

在学习了 Java 的反射机制之后,就要想要怎么把Java的反射机制应用起来?它的具体应用场景应该是什么样的?接下来,我将会用一个简单的案例来展示 Java 的反射机制在场景中的应用。

反射的触发时机

要想了解反射机制在什么时候发生作用,首先就要先了解​类加载的过程​。在冯·诺依曼定义的计算机模型中,任何的程序都需要加载到内存中才可以和 CPU 进行交流。字节码 ​.class​文件也是不例外的,同样是要加载内存中才能实现实例化。而​类加载​就是将一个​.class​字节码文件实例化成​java.lang.Class​对象,并进行相关初始化的过程。

类加载的过程

反射的常见应用场景

(1)反射机制的典型应用——Tomcat服务器

(2)数据库驱动的加载——使用 JDBC 连接数据库时使用 Class.forName()

(3)框架设计的底层——Spring框架的IOC控制反转

(4)对于繁重冗杂重复的代码进行优化

    ……

反射案例实例展示

业务需求:开发一个工具类,在不修改工具类的代码基础上,用户只需要在配置文件中简单配置完成对象的创建和方法的调用。

程序设计:

游戏中有两个可以供选择英雄

角色1:安琪拉

职业:中单

技能:在程序中使用public来修饰,代表角色行为的方法。

被动:在程序中使用private来修饰,代表角色行为的方法。

角色2:凯

职业:上单

技能:在程序中使用public来修饰,代表角色行为的方法。

被动:在程序中使用private来修饰,代表角色行为的方法。

这时候我们需要一个配置文件来供玩家配置想要选择的英雄角色以及要释放的技能。

people.properties

创建一个普通的maven工程,利用反射机制实现上述的业务,工程目录如下:

工程目录结构

定义角色1 AnQiLa:

package com.demo.roles;

public class AnQiLa {
    private String name="安琪拉";
    private String job="中单";

    //私有化角色触发被动技能的方法
    private String getPassiveSkill(){
        return name+": [触发了被动技能!]";
    }

    //角色一技能
    public String getFirstSkill(){
        return name+": [在中路使用了一技能]";

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

定义角色2:

package com.demo.roles;

public class Kai {
    private String name="凯";
    private String job="上单";

    //私有化角色触发被动技能的方法
    private String getPassiveSkill(){
        return name+": [触发了被动技能!]";
    }

    //角色一技能
    public String getFirstSkill(){
        return name+": [在上路使用了一技能]";

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }
}

定义工具类:

package com.demo.controller;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectUtil {
    public static void main(String[] args) throws Exception {
        //加载玩家配置信息
        Properties properties = new Properties();
        ClassLoader classLoader = ReflectUtil.class.getClassLoader();
        InputStream resourceAsStream = classLoader.getResourceAsStream("people.properties");
        properties.load(resourceAsStream);

        //从配置文件中读取玩家选择的英雄角色
        String role = properties.getProperty("object.role");
        //从配置文件中读取玩家使用的技能
        String actions = properties.getProperty("method.skills");
        String[] skills = actions.split(",");

        //通过反射实例化玩家选择的角色对象
        Class aClass = Class.forName(role);
        Object instance = aClass.newInstance();

        //遍历玩家选择使用的技能
        for (String skill : skills) {
            //获取玩家使用角色的所有技能
            Method declaredSkill = aClass.getDeclaredMethod(skill);
            //判断获得的技能是否私有
            if (declaredSkill.toString().contains("private")) {
                //如果是私有的被动技能,则需设置私有技能可使用
                declaredSkill.setAccessible(true);
                //使用被动
                Object invoke = declaredSkill.invoke(instance, null);
                System.out.println(invoke.toString());
            } else {
                //如果是普通技能 则可以直接访问
                Object invoke = declaredSkill.invoke(instance, null);
                System.out.println(invoke.toString());
            }
        }
    }
}

剩下的就只要玩家在配置文件​people.properties​中更改配置,工具类就会帮助玩家完成相应的角色创建和技能释放。

#玩家配置需要选择的英雄角色
#选择AnQiLa[安琪拉]
object.role=com.demo.roles.AnQiLa
#玩家配置需要使用的技能,多个技能之间用英文逗号隔开
#选择使用一技能并触发私有的被动技能
method.skills=getPassiveSkill,getFirstSkill

运行结果1:

安琪拉: [触发了被动技能!] 
安琪拉: [在中路使用了一技能] 
 Process finished with exit code 0

想要更换英雄,就可以修改配置文件中的内容:

#玩家配置需要选择的英雄角色
#选择Kai[凯]
object.role=com.demo.roles.Kai
#玩家配置需要使用的技能,多个技能之间用英文逗号隔开
#选择使用一技能并触发私有的被动技能
method.skills=getPassiveSkill,getFirstSkill

运行结果2:

凯: [触发了被动技能!] 
凯: [在上路使用了一技能] 
 Process finished with exit code 0

总结

以上就是关于 Java 反射机制的应用,以及具体代码实例展示的全部内容。如果本篇文章对各位的学习有所帮助,还希望大家能够多多地关注和支持W3Cschool


0 人点赞