在學(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ā)生作用,首先就要先了解?類加載的過(guò)程
?。在馮·諾依曼定義的計(jì)算機(jī)模型中,任何的程序都需要加載到內(nèi)存中才可以和 CPU 進(jìn)行交流。字節(jié)碼 ?.class
?文件也是不例外的,同樣是要加載內(nèi)存中才能實(shí)現(xiàn)實(shí)例化。而?類加載
?就是將一個(gè)?.class
?字節(jié)碼文件實(shí)例化成?java.lang.Class
?對(duì)象,并進(jìn)行相關(guān)初始化的過(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è)工具類,在不修改工具類的代碼基礎(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ù),工程目錄如下:
定義角色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;
}
}
定義工具類:
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
?中更改配置,工具類就會(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!