亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java中反射(Reflection)機(jī)制舉例詳解

 更新時(shí)間:2025年03月31日 09:43:50   作者:的的小白  
Java中的反射機(jī)制是指Java程序在運(yùn)行期間可以獲取到一個(gè)對(duì)象的全部信息,這篇文章主要介紹了java中反射(Reflection)機(jī)制的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

一、什么是反射?

反射(Reflection)是一種 Java 程序運(yùn)行期間動(dòng)態(tài)技術(shù),可以在運(yùn)行時(shí)(runtime)檢査、修改其自身結(jié)構(gòu)或行為。通過(guò)反射,程序可以訪問(wèn)、檢測(cè)和修改它自己的類、對(duì)象、方法、屬性等成員

二、反射的用途

  • 動(dòng)態(tài)加載類:程序可以在運(yùn)行時(shí)動(dòng)態(tài)地加載類庫(kù)中的類;
  • 動(dòng)態(tài)創(chuàng)建對(duì)象:反射可以基于類的信息,程序可以在運(yùn)行時(shí),動(dòng)態(tài)創(chuàng)建對(duì)象實(shí)例;
  • 調(diào)用方法:反射可以根據(jù)方法名稱,程序可以在運(yùn)行時(shí),動(dòng)態(tài)地調(diào)用對(duì)象的方法(即使方法在編寫(xiě)程序時(shí)還沒(méi)有定義)
  • 訪問(wèn)成員變量:反射可以根據(jù)成員變量名稱,程序可以在運(yùn)行時(shí),訪問(wèn)和修改成員變量(反射可以訪問(wèn)私有成員變量)
  • 運(yùn)行時(shí)類型信息:反射允許程序在運(yùn)行時(shí),查詢對(duì)象的類型信息,這對(duì)于編寫(xiě)通用的代碼和庫(kù)非常有用;

                Spring 框架使用反射來(lái)自動(dòng)裝配組件,實(shí)現(xiàn)依賴注入;

                MyBatis 框架使用反射來(lái)創(chuàng)建resultType 對(duì)象,封裝數(shù)據(jù)查詢結(jié)果;

三、獲取Class對(duì)象

反射的第一步是獲取 Class 對(duì)象。Class 對(duì)象表示某個(gè)類的元數(shù)據(jù),可以通過(guò)以下幾種方式獲?。?/p>

//獲取Class類型信息
public class Text02 {
	public static void main(String[] args) throws ClassNotFoundException {
		//方式1:通過(guò)類名
		Class stringClass1 = String.class;
		
		//方式2:通過(guò)Class類的forName()方法
		Class stringClass2 = Class.forName("java.lang.String");
		
		//方式3:通過(guò)對(duì)象調(diào)用getClass()方法
		Class stringClass3 = "".getClass();
		
		System.out.println(stringClass1.hashCode());//1604839423
		System.out.println(stringClass2.hashCode());//1604839423
		System.out.println(stringClass3.hashCode());//1604839423
	}

}

四、Class類型的對(duì)象使用場(chǎng)景1

將一個(gè) JSON 字符串解析為 Java 對(duì)象,并輸出該對(duì)象的字段值。

//Class類型的對(duì)象使用場(chǎng)景1
public class Text03 {
	public static void main(String[] args) {
		String json= "{\"name\":\"長(zhǎng)安荔枝\",\"favCount\":234}";
		
		//方法定義
		Document doc=JSON.parseObject(json,Document.class);
		System.out.println(doc.getName());
		System.out.println(doc.getFavCount());
	}

}

使用 JSON.parseObject 方法將 JSON 字符串解析為 Document 類的對(duì)象。在解析過(guò)程中,JSON 字符串中的數(shù)據(jù)會(huì)自動(dòng)映射到 Document 類的對(duì)應(yīng)字段中。

五、Class類型的對(duì)象使用場(chǎng)景2

通過(guò) Class 對(duì)象在運(yùn)行時(shí)獲取一個(gè)類的相關(guān)信息,包括類名、包名、成員變量(字段)、成員方法等。

//Class類型的對(duì)象使用場(chǎng)景2
//獲取豐富的類型內(nèi)容
public class Text04 {
	public static void main(String[] args) throws ClassNotFoundException {
		Class clz = Class.forName("java.util.HashMap");
		
		//獲取類名
		System.out.println("完全限定名:"+clz.getName());
		System.out.println("簡(jiǎn)單的類名:"+clz.getSimpleName());
		
		//獲取包名
		System.out.println("package"+clz.getPackage().getName());
		System.out.println();
		
		//獲取成員變量
		Field[] fieldArray =clz.getDeclaredFields();
		System.out.println("成員變量(字段)");
		for(Field field:fieldArray) {
			System.out.println(field);
		}
		System.out.println();
		
		//獲取成員方法
		Method[] methodArray = clz.getDeclaredMethods();
		System.out.println("成員方法");
		for(Method method:methodArray) {
			System.out.println(method);
		}	
	}
}
  • clz.getName() 返回類的完全限定名,包括包名,例如 "java.util.HashMap"。
  • clz.getSimpleName() 返回類的簡(jiǎn)單名稱,不包括包名,例如 "HashMap"。
  • clz.getPackage().getName() 返回類所屬的包名,例如 "java.util"。
  • clz.getDeclaredFields() 返回一個(gè) Field 數(shù)組,包含了類聲明的所有字段(包括私有字段)。
  • clz.getDeclaredMethods() 返回一個(gè) Method 數(shù)組,包含了類聲明的所有方法(包括私有方法)。

六、通過(guò)反射創(chuàng)建對(duì)象

方式一:通過(guò) Class 對(duì)象直接調(diào)用 newInstance() 方法

方式二:通過(guò)獲取構(gòu)造方法(Constructor)來(lái)創(chuàng)建對(duì)象。

//通過(guò)反射的方式,創(chuàng)建對(duì)象
public class Text05 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class clz = Class.forName("com.apesource.demo01.Document");
		
		//方式1:直接通過(guò)Class對(duì)象,調(diào)用newInstance()方法
		Object objx = clz.newInstance();//相當(dāng)于在執(zhí)行無(wú)參構(gòu)造方法
		
		//方式2:通過(guò)構(gòu)造器(構(gòu)造方法)
		//無(wú)參構(gòu)造方法
		Constructor constructor1 = clz.getDeclaredConstructor();//獲取無(wú)參構(gòu)造方法
		System.out.println(constructor1);
		Object obj1 = constructor1.newInstance();//執(zhí)行構(gòu)造器(構(gòu)造方法),創(chuàng)建對(duì)象
		
		//有參構(gòu)造方法
		Constructor constructor2 = clz.getDeclaredConstructor(String.class);//獲取有參構(gòu)造方法
		System.out.println(constructor2);
		Object obj2 = constructor2.newInstance("兩京十五日");
		
		Constructor constructor3 = clz.getDeclaredConstructor(int.class);//獲取有參構(gòu)造方法
		System.out.println(constructor3);
		Object obj3 = constructor3.newInstance(34);
		
		Constructor constructor4 = clz.getDeclaredConstructor(String.class,int.class);//獲取有參構(gòu)造方法
		System.out.println(constructor4);
		Object obj4 = constructor4.newInstance("風(fēng)起隴西",64);
		
		System.out.println(objx);
		System.out.println(obj1);
		System.out.println(obj2);
		System.out.println(obj3);
		System.out.println(obj4);
	}
  • newInstance() 方法是 Class 對(duì)象提供的一個(gè)方法,它調(diào)用類的無(wú)參構(gòu)造方法來(lái)創(chuàng)建類的實(shí)例。
  • 注意:這個(gè)方法在 Java 9 以后已經(jīng)被棄用,推薦使用 Constructor 對(duì)象來(lái)創(chuàng)建實(shí)例。
  • 通過(guò) getDeclaredConstructor() 方法獲取 Document 類的無(wú)參構(gòu)造方法,然后調(diào)用 newInstance() 方法創(chuàng)建實(shí)例。
  • 注意:如果類中沒(méi)有無(wú)參構(gòu)造方法,調(diào)用 getDeclaredConstructor() 會(huì)拋出 NoSuchMethodException。
  • 通過(guò) getDeclaredConstructor(String.class) 獲取帶有一個(gè) String 參數(shù)的構(gòu)造方法,并傳入 "兩京十五日" 作為參數(shù)來(lái)創(chuàng)建對(duì)象。
  • 通過(guò) getDeclaredConstructor(int.class) 獲取帶有一個(gè) int 參數(shù)的構(gòu)造方法,并傳入 34 作為參數(shù)來(lái)創(chuàng)建對(duì)象。

七、使用 Java 反射機(jī)制獲取和調(diào)用類的構(gòu)造方法,訪問(wèn)私有構(gòu)造方法并創(chuàng)建對(duì)象

public class Text06 {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class clz = Class.forName("com.apesource.demo01.Document");
		
		//獲取一組構(gòu)造器
		Constructor[] constructorArray1 = clz.getConstructors();//public
		Constructor[] constructorArray2 = clz.getDeclaredConstructors();//public、private
		
		//獲取指定構(gòu)造器
		Constructor constructor1 = clz.getConstructor();
		Constructor constructor2 = clz.getDeclaredConstructor(String.class);
		System.out.println(constructor1);
		System.out.println(constructor2);
		
		//調(diào)用私有構(gòu)造器,必須設(shè)置它的訪問(wèn)全限
		constructor2.setAccessible(true);
		
		//調(diào)用構(gòu)造器,創(chuàng)建對(duì)象
		Object obj = constructor2.newInstance("長(zhǎng)安三萬(wàn)里");
		System.out.println(obj);
	}

}
  • getConstructors() 方法返回一個(gè)包含所有公共(public)構(gòu)造方法的數(shù)組。如果類中沒(méi)有 public 構(gòu)造方法,則返回空數(shù)組。
  • getDeclaredConstructors() 方法返回一個(gè)包含所有聲明的構(gòu)造方法的數(shù)組(包括私有的、受保護(hù)的和默認(rèn)訪問(wèn)級(jí)別的構(gòu)造方法)。
  • getConstructor() 方法用于獲取類的無(wú)參構(gòu)造方法(必須是 public 的)。如果沒(méi)有無(wú)參構(gòu)造方法或者不是 public,則拋出 NoSuchMethodException。
  • getDeclaredConstructor(Class<?>... parameterTypes) 方法用于獲取指定參數(shù)類型的構(gòu)造方法。這里通過(guò)傳入 String.class 參數(shù)獲取一個(gè)帶有 String 參數(shù)的構(gòu)造方法。這個(gè)構(gòu)造方法可以是任何訪問(wèn)級(jí)別(public、privateprotected、默認(rèn))。
  • setAccessible(true) 用于繞過(guò) Java 訪問(wèn)控制機(jī)制,使私有構(gòu)造方法也可以被調(diào)用。如果不設(shè)置 Accessible 為 true,那么調(diào)用私有構(gòu)造方法時(shí)會(huì)拋出 IllegalAccessException。
  • newInstance(Object... initargs) 方法使用指定的構(gòu)造方法創(chuàng)建對(duì)象。這里調(diào)用了帶有 String 參數(shù)的構(gòu)造方法,并傳入 "長(zhǎng)安三萬(wàn)里" 作為參數(shù)。

八、通過(guò)反射,訪問(wèn)并使用成員方法

public class Text08 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		//硬編碼的方式
//		Document doc1 = new Document();
//		doc1.setName("海底兩萬(wàn)里");
//		doc1.setFavCount(10025);
		
		//反射的方式
		Class clz = Class.forName("com.apesource.demo01.Document");//獲取類型信息
		Object doc1 = clz.newInstance();//創(chuàng)建對(duì)象
		
		//獲取指定名稱和參數(shù)類型的方法
		Method setNameMethod = clz.getMethod("setName", String.class);
		Method setFavCountMethod = clz.getMethod("setFavCount", int.class);
		
		//執(zhí)行方法
		//doc1.setName("海底兩萬(wàn)里");
		setNameMethod.invoke(doc1, "海底兩萬(wàn)里");
		//doc1.setFavCount(10025);
		setFavCountMethod.invoke(doc1, 10025);
		
		System.out.println(doc1);
		
	}

}
  • getMethod(String name, Class<?>... parameterTypes) 方法用于獲取類的某個(gè) public 方法。方法名稱和參數(shù)類型必須匹配才能成功獲取方法。
  • invoke(Object obj, Object... args) 方法用于調(diào)用指定的實(shí)例方法。
  • setNameMethod.invoke(doc1, "海底兩萬(wàn)里"); 等同于 doc1.setName("海底兩萬(wàn)里");。
  • setFavCountMethod.invoke(doc1, 10025); 等同于 doc1.setFavCount(10025);。

九、通過(guò)反射,調(diào)用靜態(tài)方法以及處理可變參數(shù)

public class Text09_01 {
	public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException {
		//硬編碼的方式
		//調(diào)用靜態(tài)方法
//		Document.dosth();
		
		String ret1 = String.format("HashMap的默認(rèn)初始容量是%d,加載因子是%.2f", 16,0.75f);
		System.out.println(ret1);
		
		
		//反射的方式
//		Class clz = Class.forName("com.apesource.demo01.Document");
//		Method dosthMethod = clz.getMethod("dosth");
//		dosthMethod.invoke(null);
		
		Class clz = String.class;
		Method formatMethod = clz.getMethod("format", String.class,Object[].class);
		String ret2 = formatMethod.invoke(null, "HashMap的默認(rèn)初始容量是%d,加載因子是%.2f",new Object[] {16,0.75f}).toString();
		
		System.out.println(ret2);
	}

}
  • 這是直接調(diào)用靜態(tài)方法的傳統(tǒng)方式。假設(shè) Document 類有一個(gè)名為 dosth() 的靜態(tài)方法,可以直接使用類名調(diào)用。
  • String.format 是一個(gè)靜態(tài)方法,用于格式化字符串,類似于 printf 的格式化規(guī)則
  • 獲取 String 類的 Class 對(duì)象:使用 Class clz = String.class;。
  • 獲取 String 類的 Class 對(duì)象:使用 Class clz = String.class;。
  • 調(diào)用靜態(tài)方法:使用 invoke(null, "HashMap的默認(rèn)初始容量是%d,加載因子是%.2f", new Object[] {16, 0.75f}) 調(diào)用靜態(tài)方法,因?yàn)?nbsp;format 是靜態(tài)方法,所以第一個(gè)參數(shù)是 null。
  • 注意invoke 方法中,Object[] 參數(shù)必須以數(shù)組形式傳遞,所以用了 new Object[] {16, 0.75f}。

十、反射的性能問(wèn)題

反射雖然功能強(qiáng)大,但由于是在運(yùn)行時(shí)動(dòng)態(tài)操作類,因此性能相對(duì)較低。此外,反射也會(huì)破

壞封裝性,使用時(shí)要謹(jǐn)慎。

十一、反射的安全性

使用反射時(shí)需要注意安全問(wèn)題,因?yàn)樗梢岳@過(guò) Java 的訪問(wèn)控制機(jī)制。例如,可以訪問(wèn)私有

字段或方法,因此在開(kāi)發(fā)中使用反射要特別小心。

十二、反射的常見(jiàn)場(chǎng)景

  • 框架開(kāi)發(fā):如 Spring 中的依賴注入、Hibernate 中的 ORM 等。
  • 調(diào)試工具:如 Java 的調(diào)試器、分析工具等。
  • 動(dòng)態(tài)代理:在 Java 中,動(dòng)態(tài)代理依賴于反射。

總結(jié) 

到此這篇關(guān)于java中反射(Reflection)機(jī)制的文章就介紹到這了,更多相關(guān)java反射Reflection內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mybatis如何通過(guò)接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行詳解

    mybatis如何通過(guò)接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行詳解

    這篇文章主要給大家介紹了利用mybatis如何通過(guò)接口查找對(duì)應(yīng)的mapper.xml及方法執(zhí)行的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。
    2017-06-06
  • 智能手表開(kāi)發(fā)API接口

    智能手表開(kāi)發(fā)API接口

    這篇文章主要介紹了智能手表開(kāi)發(fā)API接口,使用圖靈機(jī)器人平臺(tái)接口實(shí)現(xiàn)天氣預(yù)報(bào),非常簡(jiǎn)單實(shí)用,這里推薦給大家。
    2015-03-03
  • 一文徹底搞定Java中常用集合的排序方法

    一文徹底搞定Java中常用集合的排序方法

    在某些特殊的場(chǎng)景下我們需要在Java程序中對(duì)List集合進(jìn)行排序操作,下面這篇文章主要給大家介紹了關(guān)于Java中常用集合的排序方法的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • SpringBoot使用AOP,內(nèi)部方法失效的解決方案

    SpringBoot使用AOP,內(nèi)部方法失效的解決方案

    這篇文章主要介紹了SpringBoot使用AOP,內(nèi)部方法失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • springboot中nacos-client獲取配置的實(shí)現(xiàn)方法

    springboot中nacos-client獲取配置的實(shí)現(xiàn)方法

    本文主要介紹了springboot中nacos-client獲取配置的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java中常用解析工具jackson及fastjson的使用

    Java中常用解析工具jackson及fastjson的使用

    今天給大家?guī)?lái)的是關(guān)于Java解析工具的相關(guān)知識(shí),文章圍繞著jackson及fastjson的使用展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • maven中profile的使用

    maven中profile的使用

    本文主要介紹了maven中profile的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Springboot和bootstrap實(shí)現(xiàn)shiro權(quán)限控制配置過(guò)程

    Springboot和bootstrap實(shí)現(xiàn)shiro權(quán)限控制配置過(guò)程

    這篇文章主要介紹了Springboot和bootstrap實(shí)現(xiàn)shiro權(quán)限控制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 關(guān)于Java垃圾回收開(kāi)銷降低的幾條建議

    關(guān)于Java垃圾回收開(kāi)銷降低的幾條建議

    垃圾回收(Garbage Collection)是Java虛擬機(jī)(JVM)垃圾回收器提供的一種用于在空閑時(shí)間不定時(shí)回收無(wú)任何對(duì)象引用的對(duì)象占據(jù)的內(nèi)存空間的一種機(jī)制,下面這篇文章主要介紹了關(guān)于Java垃圾回收開(kāi)銷降低的幾條建議,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-02-02
  • Java編程實(shí)現(xiàn)打印螺旋矩陣實(shí)例代碼

    Java編程實(shí)現(xiàn)打印螺旋矩陣實(shí)例代碼

    這篇文章主要介紹了Java編程實(shí)現(xiàn)打印螺旋矩陣實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12

最新評(píng)論