App下載

用案例來(lái)展示Java反射機(jī)制的應(yīng)用

猿友 2021-07-20 15:52:29 瀏覽數(shù) (2363)
反饋

在學(xué)習(xí)了 Java 的反射機(jī)制之后,就要想要怎么把Java的反射機(jī)制應(yīng)用起來(lái)?它的具體應(yīng)用場(chǎng)景應(yīng)該是什么樣的?接下來(lái),我將會(huì)用一個(gè)簡(jiǎn)單的案例來(lái)展示 Java 的反射機(jī)制在場(chǎng)景中的應(yīng)用。

反射的觸發(fā)時(shí)機(jī)

要想了解反射機(jī)制在什么時(shí)候發(fā)生作用,首先就要先了解?類(lèi)加載的過(guò)程?。在馮·諾依曼定義的計(jì)算機(jī)模型中,任何的程序都需要加載到內(nèi)存中才可以和 CPU 進(jìn)行交流。字節(jié)碼 ?.class?文件也是不例外的,同樣是要加載內(nèi)存中才能實(shí)現(xiàn)實(shí)例化。而?類(lèi)加載?就是將一個(gè)?.class?字節(jié)碼文件實(shí)例化成?java.lang.Class?對(duì)象,并進(jìn)行相關(guān)初始化的過(guò)程。

類(lèi)加載的過(guò)程

反射的常見(jiàn)應(yīng)用場(chǎng)景

(1)反射機(jī)制的典型應(yīng)用——Tomcat服務(wù)器

(2)數(shù)據(jù)庫(kù)驅(qū)動(dòng)的加載——使用 JDBC 連接數(shù)據(jù)庫(kù)時(shí)使用 Class.forName()

(3)框架設(shè)計(jì)的底層——Spring框架的IOC控制反轉(zhuǎn)

(4)對(duì)于繁重冗雜重復(fù)的代碼進(jìn)行優(yōu)化

    ……

反射案例實(shí)例展示

業(yè)務(wù)需求:開(kāi)發(fā)一個(gè)工具類(lèi),在不修改工具類(lèi)的代碼基礎(chǔ)上,用戶只需要在配置文件中簡(jiǎn)單配置完成對(duì)象的創(chuàng)建和方法的調(diào)用。

程序設(shè)計(jì):

游戲中有兩個(gè)可以供選擇英雄

角色1:安琪拉

職業(yè):中單

技能:在程序中使用public來(lái)修飾,代表角色行為的方法。

被動(dòng):在程序中使用private來(lái)修飾,代表角色行為的方法。

角色2:凱

職業(yè):上單

技能:在程序中使用public來(lái)修飾,代表角色行為的方法。

被動(dòng):在程序中使用private來(lái)修飾,代表角色行為的方法。

這時(shí)候我們需要一個(gè)配置文件來(lái)供玩家配置想要選擇的英雄角色以及要釋放的技能。

people.properties

創(chuàng)建一個(gè)普通的maven工程,利用反射機(jī)制實(shí)現(xiàn)上述的業(yè)務(wù),工程目錄如下:

工程目錄結(jié)構(gòu)

定義角色1 AnQiLa:

package com.demo.roles;

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

    //私有化角色觸發(fā)被動(dòng)技能的方法
    private String getPassiveSkill(){
        return name+": [觸發(fā)了被動(dòng)技能!]";
    }

    //角色一技能
    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="上單";

    //私有化角色觸發(fā)被動(dòng)技能的方法
    private String getPassiveSkill(){
        return name+": [觸發(fā)了被動(dòng)技能!]";
    }

    //角色一技能
    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;
    }
}

定義工具類(lèi):

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(",");

        //通過(guò)反射實(shí)例化玩家選擇的角色對(duì)象
        Class aClass = Class.forName(role);
        Object instance = aClass.newInstance();

        //遍歷玩家選擇使用的技能
        for (String skill : skills) {
            //獲取玩家使用角色的所有技能
            Method declaredSkill = aClass.getDeclaredMethod(skill);
            //判斷獲得的技能是否私有
            if (declaredSkill.toString().contains("private")) {
                //如果是私有的被動(dòng)技能,則需設(shè)置私有技能可使用
                declaredSkill.setAccessible(true);
                //使用被動(dòng)
                Object invoke = declaredSkill.invoke(instance, null);
                System.out.println(invoke.toString());
            } else {
                //如果是普通技能 則可以直接訪問(wèn)
                Object invoke = declaredSkill.invoke(instance, null);
                System.out.println(invoke.toString());
            }
        }
    }
}

剩下的就只要玩家在配置文件?people.properties?中更改配置,工具類(lèi)就會(huì)幫助玩家完成相應(yīng)的角色創(chuàng)建和技能釋放。

#玩家配置需要選擇的英雄角色
#選擇AnQiLa[安琪拉]
object.role=com.demo.roles.AnQiLa
#玩家配置需要使用的技能,多個(gè)技能之間用英文逗號(hào)隔開(kāi)
#選擇使用一技能并觸發(fā)私有的被動(dòng)技能
method.skills=getPassiveSkill,getFirstSkill

運(yùn)行結(jié)果1:

安琪拉: [觸發(fā)了被動(dòng)技能!] 
安琪拉: [在中路使用了一技能] 
 Process finished with exit code 0

想要更換英雄,就可以修改配置文件中的內(nèi)容:

#玩家配置需要選擇的英雄角色
#選擇Kai[凱]
object.role=com.demo.roles.Kai
#玩家配置需要使用的技能,多個(gè)技能之間用英文逗號(hào)隔開(kāi)
#選擇使用一技能并觸發(fā)私有的被動(dòng)技能
method.skills=getPassiveSkill,getFirstSkill

運(yùn)行結(jié)果2:

凱: [觸發(fā)了被動(dòng)技能!] 
凱: [在上路使用了一技能] 
 Process finished with exit code 0

總結(jié)

以上就是關(guān)于 Java 反射機(jī)制的應(yīng)用,以及具體代碼實(shí)例展示的全部?jī)?nèi)容。如果本篇文章對(duì)各位的學(xué)習(xí)有所幫助,還希望大家能夠多多地關(guān)注和支持W3Cschool!


0 人點(diǎn)贊