java反射常用方法案例詳解
1.反射概述
Java反射指的是一個(gè)機(jī)制,這種機(jī)制可以在Java程序運(yùn)行時(shí)(動(dòng)態(tài))實(shí)例化對(duì)象、讀寫(xiě)屬性、調(diào)用方法。
關(guān)鍵詞:運(yùn)行時(shí)
一般在我們開(kāi)發(fā)程序時(shí),都知道自己具體用的什么類,直接創(chuàng)建即可。但是當(dāng)寫(xiě)一些通用的功能時(shí),就不能在編譯時(shí)把具體類的類型寫(xiě)死,因?yàn)槌绦蜻\(yùn)行起來(lái)后可能會(huì)有多種類型的可能,此時(shí)就需要在運(yùn)行時(shí)動(dòng)態(tài)的去調(diào)用某個(gè)類的屬性和方法,這就必須通過(guò)反射來(lái)實(shí)現(xiàn)。
案例:
// 不知道調(diào)用者傳入什么類型對(duì)象。
public static String instance(Object obj) {
……
}如何知道方法的參數(shù)Object是什么類型?
一般有兩種做法:
第一種做法:是知道參數(shù)類型有哪幾種情況,可以使用instanceof運(yùn)算符進(jìn)行判斷,再利用強(qiáng)制類型轉(zhuǎn)換將其轉(zhuǎn)換成其運(yùn)行時(shí)類型的變量即可。
public static String getTypeInstanceof(Object obj){
// 學(xué)生
if (obj instanceof Student){
Student student = (Student) obj;
String userType = student.getUserType("王明");
return userType;
}
// 老師
if (obj instanceof Teacher){
Teacher teacher = (Teacher) obj;
String userType = teacher.getUserType("王明");
return userType;
}
return null;
}第二種做法:在編譯時(shí)根本無(wú)法預(yù)知該對(duì)象和類可能屬于哪些類,程序只依靠運(yùn)行時(shí)信息動(dòng)態(tài)的來(lái)發(fā)現(xiàn)該對(duì)象和類的真實(shí)信息,這就必須使用反射。
public static String getType(Object obj) {
// 通過(guò)反射獲取運(yùn)行時(shí)類
Class<?> aClass = obj.getClass();
try {
// 實(shí)例化對(duì)象
Object instance = aClass.newInstance();
// 調(diào)用getUserType方法
// 匹配對(duì)象中的getUserType()方法,參數(shù)類型為String
Method method02 = aClass.getMethod("getUserType", String.class);
// 調(diào)用匹配的方法,傳入?yún)?shù)
String invoke = (String) method02.invoke(instance, "王明");
return invoke;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}案例全部代碼:
public class Demo1 {
public static void main(String[] args) {
// 測(cè)試Instanceof方式
Teacher teacher = new Teacher();
String typeInstanceof = getTypeInstanceof(teacher);
System.out.println(typeInstanceof);
// 測(cè)試反射方式
Student student = new Student();
String type = getType(student);
System.out.println(type);
}
public static String getTypeInstanceof(Object obj){
// 學(xué)生
if (obj instanceof Student){
Student student = (Student) obj;
String userType = student.getUserType("王明");
return userType;
}
// 老師
if (obj instanceof Teacher){
Teacher teacher = (Teacher) obj;
String userType = teacher.getUserType("王明");
return userType;
}
return null;
}
/**
* 獲取用戶類型方法(老師、學(xué)生...)
*/
public static String getType(Object obj) {
// 通過(guò)反射獲取運(yùn)行時(shí)類
Class<?> aClass = obj.getClass();
try {
// 實(shí)例化對(duì)象
Object instance = aClass.newInstance();
// 調(diào)用getUserType方法
// 匹配對(duì)象中的getUserType()方法,參數(shù)類型為String
Method method02 = aClass.getMethod("getUserType", String.class);
// 調(diào)用匹配的方法,傳入?yún)?shù)
String invoke = (String) method02.invoke(instance, "王明");
return invoke;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 學(xué)生類
*/
static class Student {
public String getUserType(String str) {
System.out.println(str);
return "學(xué)生-" + str;
}
}
/**
* 老師類
*/
static class Teacher {
public String getUserType(String str) {
System.out.println(str);
return "老師-" + str;
}
}
}2. 反射獲取Class對(duì)象的三種方式
通過(guò)反射去使用一個(gè)類,首先我們要獲取到該類的字節(jié)碼文件對(duì)象,也就是類型為Class類型的對(duì)象。
方式一:Class.forName("包名.類名") - 常用方式
例如:Class.forName("com.kexuekt.Student");
方式二:使用類的class屬性來(lái)獲取該類對(duì)應(yīng)的Class對(duì)象
例如: Student.class;
方式三:調(diào)用對(duì)象的getClass()方法,該方法是Object類中的方法,因?yàn)槊總€(gè)類默認(rèn)繼承了Object類,所有的Java對(duì)象都可以調(diào)用該方法
例如:
Student stu = new Student();
stu.getClass();
3.反射常用方法
3.1反射獲取構(gòu)造方法
- Constructor<?>[] getDeclaredConstructors?():獲取所有構(gòu)造方法
- Constructor<?>[] getConstructors?():獲取所有public構(gòu)造方法
- Constructor<T> getConstructor?():獲取無(wú)參構(gòu)造方法
- Constructor<T> getDeclaredConstructor?(Class<?>... parameterTypes):根據(jù)參數(shù)類型獲取有參構(gòu)造方法
- 創(chuàng)建實(shí)例化對(duì)象方法 T newInstance?(Object... initargs):根據(jù)指定的構(gòu)造方法創(chuàng)建對(duì)象
3.2反射獲取成員變量
- Field[] getDeclaredFields?():獲取所有成員變量
- Field getDeclaredField?(String name):獲取單個(gè)成員變量
- Field[] getFields?():獲取所有public成員變量
- Field getField?(String name):獲取單個(gè)public成員變量
- Field類中用于給成員變量賦值的方法void set?(Object obj, Object value):給obj對(duì)象的成員變量賦值為value
私有成員變量設(shè)置值,需要取消訪問(wèn)權(quán)限檢查 Field.setAccessible(true);
3.3反射獲取成員方法
- Method[] getMethods?():獲取所有public成員方法,包括繼承的
- Method[] getDeclaredMethods?():獲取所有成員方法,不包括繼承的
- Method getMethod?(String name, Class<?>... parameterTypes) :獲取單個(gè)public成員方法
- Method getDeclaredMethod?(String name, Class<?>... parameterTypes):獲取單個(gè)成員方法
- Method類中用于調(diào)用成員方法的方法Object invoke?(Object obj, Object... args):調(diào)用obj對(duì)象的成員方法,參數(shù)是args,返回值是Object類型
3.4反射獲取構(gòu)造、成員變量、成員方法Demo
學(xué)生類
class Student {
private String name;
public Integer age;
public Student(){
}
public Student(String name, Integer age){
this.name = name;
this.age = age;
}
private String getUserType(String str) {
System.out.println(str);
return "學(xué)生-" + str;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}獲取構(gòu)造方法Demo
獲取無(wú)參構(gòu)造方法
Class aClass = Student.class; Constructor constructor = aClass.getConstructor(); Student newInstance = (Student)constructor.newInstance();
根據(jù)參數(shù)類型獲取有參構(gòu)造方法
// 根據(jù)參數(shù)類型獲取構(gòu)造方法
Class aClass = Student.class;
Class<?>[] classes = {Class.forName("java.lang.String"), Class.forName("java.lang.Integer")};
Constructor c = aClass.getDeclaredConstructor(classes);
Student student = (Student)c.newInstance("王明", 1);
System.out.println(student.toString());獲取成員變量方法
獲取所有成員變量方法
Class aClass = Student.class;
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
System.out.println(field.getName());
}獲取指定成員變量方法
Class aClass = Student.class;
Field name = aClass.getDeclaredField("name");給private、public成員變量賦值
// 獲取name私有成員變量
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
// 獲取age成員變量
Field age = aClass.getDeclaredField("age");
// 通過(guò)反射實(shí)例化對(duì)象
Student student = aClass.getConstructor().newInstance();
// 成員變量參數(shù)賦值
name.set(student, "王明");
age.set(student, 20);
System.out.println(student.toString());獲取成員方法
獲取本類中所有成員方法
Class aClass = Student.class;
Method[] methods = aClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}調(diào)用成員方法
// 獲取私有成員方法
Method getUserType = aClass.getDeclaredMethod("getUserType", Class.forName("java.lang.String"));
// 關(guān)閉權(quán)限檢查
getUserType.setAccessible(true);
// 實(shí)例化對(duì)象
Student student = aClass.getConstructor().newInstance();
// 調(diào)用方法,傳入?yún)?shù)
Object invoke = getUserType.invoke(student, "王亮");
System.out.println(invoke);到此這篇關(guān)于java反射常用方法的文章就介紹到這了,更多相關(guān)java反射常用方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot中隨機(jī)鹽值+雙重SHA256加密實(shí)戰(zhàn)
本文主要介紹了SpringBoot中隨機(jī)鹽值+雙重SHA256加密實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-07-07
java基于雙向環(huán)形鏈表解決丟手帕問(wèn)題的方法示例
這篇文章主要介紹了java基于雙向環(huán)形鏈表解決丟手帕問(wèn)題的方法,簡(jiǎn)單描述了丟手帕問(wèn)題,并結(jié)合實(shí)例形式給出了Java基于雙向環(huán)形鏈表解決丟手帕問(wèn)題的步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-11-11
java無(wú)鎖hashmap原理與實(shí)現(xiàn)詳解
本文主要介紹了java無(wú)鎖hashmap原理與實(shí)現(xiàn),大家參考使用吧2014-01-01
SpringBoot實(shí)現(xiàn)異步事件Event詳解
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)異步事件Event詳解,異步事件的模式,通常將一些非主要的業(yè)務(wù)放在監(jiān)聽(tīng)器中執(zhí)行,因?yàn)楸O(jiān)聽(tīng)器中存在失敗的風(fēng)險(xiǎn),所以使用的時(shí)候需要注意,需要的朋友可以參考下2023-11-11
基于Springboot實(shí)現(xiàn)JWT認(rèn)證的示例代碼
本文主要介紹了基于Springboot實(shí)現(xiàn)JWT認(rèn)證,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
Springboot?Shiro?anno不啟作用問(wèn)題及解決
在Shiro配置中遇到靜態(tài)資源被攔截的問(wèn)題,通過(guò)排除LinkedHashMap過(guò)濾次序和將過(guò)濾器手動(dòng)創(chuàng)建而不是注冊(cè)到容器中解決,同時(shí),確保JwtUtil類也不注冊(cè)到容器中,以避免請(qǐng)求報(bào)Not?authorized錯(cuò)誤2026-03-03
Java啟動(dòng)參數(shù)從基礎(chǔ)配置到高級(jí)調(diào)優(yōu)(最新整理)
文章系統(tǒng)講解Java啟動(dòng)參數(shù)分類、內(nèi)存管理配置、GC調(diào)優(yōu)策略及生產(chǎn)環(huán)境實(shí)踐,重點(diǎn)涵蓋標(biāo)準(zhǔn)/非標(biāo)準(zhǔn)參數(shù)、堆/元空間/直接內(nèi)存設(shè)置、G1/Parallel等回收器選擇,并提供壓縮指針、容器化部署等優(yōu)化建議,感興趣的朋友跟隨小編一起看看吧2025-08-08
Spring Boot 整合 Apache Dubbo的示例代碼
Apache Dubbo是一款高性能、輕量級(jí)的開(kāi)源 Java RPC 框架,這篇文章主要介紹了Spring Boot 整合 Apache Dubbo的方法,本文通過(guò)示例說(shuō)明給大家講解的非常詳細(xì),需要的朋友可以參考下2021-07-07
Java中replace與replaceAll的區(qū)別與測(cè)試
replace和replaceAll是JAVA中常用的替換字符的方法,下面這篇文章主要給大家介紹了關(guān)于Java中replace與replaceAll的區(qū)別與測(cè)試,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-09-09

