Java如何通過反射獲取Constructor、Field、Method對象
前言
在實際開發(fā)中,通過反射可以得到一個類的完整結(jié)構(gòu),包括類的構(gòu)造方法、類的屬性、類的方法,這就需要使用到j(luò)ava.lang.reflect包中的以下幾個類:
1、Constructor:表示類中的構(gòu)造方法
2、Field:表示類中的屬性
3、Method:表示類中的方法
使用反射技術(shù)獲取構(gòu)造器對象并使用
實驗類:
public class 反射機制_2實驗類 { private String name; private int age; private 反射機制_2實驗類() { System.out.println("無參構(gòu)造器執(zhí)行!"); } public 反射機制_2實驗類(String name, int age) { System.out.println("有參構(gòu)造器執(zhí)行!"); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "反射機制_2實驗類{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
獲取構(gòu)造器對象:
import org.junit.Test; import java.lang.reflect.Constructor; public class 反射機制_2構(gòu)造器獲取對象 { //1、getConstructors //獲取全部的構(gòu)造器,只能獲取public修飾的構(gòu)造器 @Test public void getConstructors(){ //獲取類對象 Class c=反射機制_2實驗類.class; //提取類中的全部的構(gòu)造器對象(這里只能拿public修飾的構(gòu)造器) Constructor[] constructors=c.getConstructors(); //遍歷構(gòu)造器 for (Constructor constructor : constructors) { System.out.println(constructor.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+constructor.getParameterCount()+"個"); } //運行結(jié)果:IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:2個 } //2、getDeclaredConstructors //獲取全部的構(gòu)造器:只要你敢寫,這里就能拿到,無所謂權(quán)限是否可及 @Test public void getDeclaredConstructors(){ //獲取類對象 Class c=反射機制_2實驗類.class; //提取類中的全部的構(gòu)造器對象 Constructor[] constructors=c.getDeclaredConstructors(); //遍歷構(gòu)造器 for (Constructor constructor : constructors) { System.out.println(constructor.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+constructor.getParameterCount()+"個"); } //運行結(jié)果: // IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:0個 // IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:2個 } //3、getConstructor //獲取某個構(gòu)造器:只能拿Public修飾的某個構(gòu)造器 @Test public void getConstructor() throws Exception { //獲取類對象 Class c=反射機制_2實驗類.class; //定位單個構(gòu)造器對象(按照參數(shù),這里定位的是有參的構(gòu)造器) Constructor cons=c.getConstructor(String.class,int.class); // Constructor cons=c.getConstructor();//如果獲取無參構(gòu)造器,但因為我設(shè)置的是private私有的,權(quán)限不足無法獲取,便會報錯 System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+cons.getParameterCount()+"個"); //運行結(jié)果:IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:2個 } //4、getDeclaredConstructor //獲取某個構(gòu)造器:只要你敢寫,這里就能拿到,無所謂權(quán)限是否可及 //一般是用這個,什么都可以獲取,并且是根據(jù)自己需要什么而獲取 @Test public void getDeclaredConstructor() throws Exception { //獲取類對象 Class c=反射機制_2實驗類.class; //定位單個構(gòu)造器對象(按照參數(shù),這里定位的是有參的構(gòu)造器) Constructor cons=c.getDeclaredConstructor(String.class,int.class); System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+cons.getParameterCount()+"個"); //運行結(jié)果:IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:2個 //獲取類對象 Class c2=反射機制_2實驗類.class; //定位單個構(gòu)造器對象(按照參數(shù)定位無參構(gòu)造器) Constructor cons2=c2.getDeclaredConstructor(); System.out.println(cons2.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+cons2.getParameterCount()+"個"); //運行結(jié)果:IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:0個 } }
Class在開發(fā)中最常見的用法就是將Class類對象實例化為自定義類的對象,即可通過一個給定的字符串(類的全限定類名)實例化一個本類的對象。將Class對象實例化為本類對象時,可以通過無參構(gòu)造完成,也可以通過有參構(gòu)造完成。
創(chuàng)建對象:
import org.junit.Test; import java.lang.reflect.Constructor; //反射可以破壞封裝性,私有的也可以執(zhí)行了 public class 反射機制_2創(chuàng)建對象 { @Test public void getDeclaredConstructor() throws Exception { //獲取類對象 Class c=反射機制_2實驗類.class; //定位單個構(gòu)造器對象(按照參數(shù),這里定位的是有參的構(gòu)造器) Constructor cons=c.getDeclaredConstructor(String.class,int.class); System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+cons.getParameterCount()+"個"); 反射機制_2實驗類 s1= (反射機制_2實驗類) cons.newInstance("狗蛋",18); System.out.println(s1); System.out.println(); //獲取類對象 Class c2=反射機制_2實驗類.class; //定位單個構(gòu)造器對象(按照參數(shù)定位無參構(gòu)造器) Constructor cons2=c2.getDeclaredConstructor(); System.out.println(cons2.getName()+"\t構(gòu)造器參數(shù)個數(shù)為:"+cons2.getParameterCount()+"個"); //如果遇到了私有的構(gòu)造器,可以暴力反射 cons2.setAccessible(true);//權(quán)限打開(只是這一次有效,并不是一直打開) 反射機制_2實驗類 s2= (反射機制_2實驗類) cons2.newInstance(); System.out.println(s2); //運行結(jié)果: //IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:2個 //有參構(gòu)造器執(zhí)行! //反射機制_2實驗類{name='狗蛋', age=18} // //IT2.反射機制_2實驗類 構(gòu)造器參數(shù)個數(shù)為:0個 //無參構(gòu)造器執(zhí)行! //反射機制_2實驗類{name='null', age=0} } }
使用反射技術(shù)獲取成員變量對象并使用
實驗類:
public class 反射機制_2實驗類2 { private String name; private int age; public static String schoolName; public static final String Name="遇安"; public 反射機制_2實驗類2() { System.out.println("無參構(gòu)造器執(zhí)行!"); } public 反射機制_2實驗類2(String name, int age) { System.out.println("有參構(gòu)造器執(zhí)行!"); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static String getSchoolName() { return schoolName; } public static void setSchoolName(String schoolName) { 反射機制_2實驗類2.schoolName = schoolName; } @Override public String toString() { return "反射機制_2實驗類2{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
獲取成員變量:
在反射操作中可以獲取一個類中的全部屬性,但是類中的屬性包括兩部分,即從父類繼承的屬性和本類定義的屬性。因此,在獲取類的屬性時也有以下兩種不同的方式:
1、獲取實現(xiàn)的接口或父類中的公共屬性:public Field [] getFields throws SecurityException
2、獲取本類中的全部屬性:public Field [] getDeclaredFields throws Exception
上述兩種方法返回的都是Field數(shù)組,每一個Field對象表示類中的一個屬性。如果要獲取屬性中的詳細信息,就需要調(diào)用Field類的方法。
import org.junit.Test; import java.lang.reflect.Field; public class 反射機制_2獲取成員變量 { //1、獲取全部的成員變量 // Field[] getDeclaredFields //獲得所有的成員變量對應(yīng)的Field對象,只要申明了就可以得到 @Test public void getDeclaredFields(){ //定位Class對象 Class c=反射機制_2實驗類2.class; //定位全部成員變量 Field [] fields=c.getDeclaredFields(); //遍歷獲取,常量也會被當做成員變量 for (Field field : fields) { System.out.println(field.getName()+"的類型是:"+field.getType()); } } //2、獲取某個成員變量對象 //Field getDeclaredField(String name) @Test public void getDeclaredField() throws Exception { //定位Class對象 Class c=反射機制_2實驗類2.class; //根據(jù)名稱定位某個成員變量 Field f=c.getDeclaredField("age"); System.out.println(f); System.out.println(f.getName()+"的類型是:"+f.getType()); } }
運行結(jié)果:
Test1、
name的類型是:class java.lang.String
age的類型是:int
schoolName的類型是:class java.lang.String
COUNTTRY的類型是:class java.lang.StringTest2、
private int IT2.反射機制_2實驗類2.age
age的類型是:int
獲取了成員變量有什么用呢?
import org.junit.Test; import java.lang.reflect.Field; public class 反射機制_2獲取成員變量 { //獲取了成員變量有什么用呢? @Test public void demo() throws Exception { //反射第一步獲取Class對象 Class c=反射機制_2實驗類2.class; //提取某個成員變量 Field f=c.getDeclaredField("age"); f.setAccessible(true);//因為我的age成員變量是用private修飾的,所以需要暴力打開權(quán)限 //作用一:賦值 反射機制_2實驗類2 s=new 反射機制_2實驗類2(); f.set(s,18);//s.setAge(18); System.out.println(s); //運行結(jié)果: // 無參構(gòu)造器執(zhí)行! //反射機制_2實驗類2{name='null', age=18}這里可以看出,成員變量被賦值成功 //作用二:取值 int age = (int) f.get(s); System.out.println(age);//18 } }
使用反射技術(shù)獲取方法對象并使用
實驗類:
public class 反射機制_2實驗類3 { private String name; public 反射機制_2實驗類3() { } public 反射機制_2實驗類3(String name) { this.name = name; } public void run(){ System.out.println("跑起來了。。"); } private void eat(){ System.out.println("累了,該吃飯了。。"); } private String eat(String name){ System.out.println("那就淺吃一下"+name+"吧"); return "針不戳"; } public static void ind(){ System.out.println("歡迎來到遇安的博客!"); } public String getName() { return name; } public void setName(String name) { this.name = name; } }
獲取成員方法:
import org.junit.Test; import java.lang.reflect.Method; public class 反射機制_2獲取成員方法 { //獲得類中的所有成員方法對象 @Test public void getDeclaredMethods(){ //獲取類對象 Class c=反射機制_2實驗類3.class; //提取全部方法,包括私有的 Method [] methods=c.getDeclaredMethods(); //遍歷全部方法 for (Method method : methods) { System.out.println(method.getName()+"返回值類型:"+method.getReturnType()+"參數(shù)個數(shù):"+method.getParameterCount()); } } //提取某個方法對象 @Test public void getDeclaredMethod() throws Exception { //獲取類對象 Class c=反射機制_2實驗類3.class; //提取單個方法對象 Method m1=c.getDeclaredMethod("eat"); Method m2=c.getDeclaredMethod("eat",String.class); //暴力打開權(quán)限 m1.setAccessible(true); m2.setAccessible(true); //觸發(fā)方法的執(zhí)行 反射機制_2實驗類3 s=new 反射機制_2實驗類3(); //注意:如果方法是沒有結(jié)果返回的,那么返回的是Null Object result =m1.invoke(s); System.out.println(result); Object result2=m2.invoke(s,"海鮮大餐"); System.out.println(result2); } }
運行結(jié)果:
累了,該吃飯了。。
null
那就淺吃一下海鮮大餐吧
針不戳
總結(jié)
到此這篇關(guān)于Java如何通過反射獲取Constructor、Field、Method對象的文章就介紹到這了,更多相關(guān)Java反射獲取對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中的HashSet詳解和使用示例_動力節(jié)點Java學(xué)院整理
HashSet 是一個沒有重復(fù)元素的集合。接下來通過實例代碼給大家介紹java中的hashset相關(guān)知識,感興趣的朋友一起看看吧2017-05-05解決Springboot中Feignclient調(diào)用時版本問題
這篇文章主要介紹了解決Springboot中Feign?client調(diào)用時版本問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03java 學(xué)習(xí)筆記(入門篇)_程序流程控制結(jié)構(gòu)和方法
程序流程控制結(jié)構(gòu)分為:順序、選擇、循環(huán)以及異常處理結(jié)構(gòu),語句是程序的基本組成單位,一般來說語句的執(zhí)行流程是按順序來進行的,但是當遇到一些特殊的條件,比如循環(huán),這時候語句就會按照流程控制結(jié)構(gòu)來進行了2013-01-01Springboot啟動不檢查JPA的數(shù)據(jù)源配置方式
這篇文章主要介紹了Springboot啟動不檢查JPA的數(shù)據(jù)源配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08