日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java反射机制浅析

發(fā)布時間:2025/3/20 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java反射机制浅析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概述:

? JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。


本文鏈接:http://blog.csdn.net/lemon_tree12138/article/details/49871515 -- Coding-Naga
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?--轉(zhuǎn)載請注明出處


反射的基本操作:

1.獲得類名

? 通過Java的反射機制我們可以獲得一個對象的類。這里的類是類的全名,包含包名。比如:org.demo.reflect.Clazz.

? 可能你會問,這個功能有什么用?其實這個功能還是很有用的。比如,我們在打日志的時候,我們就要用到這個功能,來追蹤這個日志是在什么地方被打出來的。

private String getObjectName(Object o) {if (o == null) {return null;}return o.getClass().getName();}

2.輸出一個類的所有對外可見的變量

? 注意這里是輸出所有對外可見的變量,即變量的修飾符為public.這里使用的是getFields()方法。注意,這里是可以獲得其父類中的public變量.

private void printFields(String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Field[] fields = clazz.getFields();for (Field field : fields) {System.out.println(field);}} catch(ClassNotFoundException e) {e.printStackTrace();}}

3.輸出一個類的所有成員變量

? 這里是輸出一個類的成員變量,不論它是不是對外可見的。就算它是被private修飾,也同樣可見。這一點很讓人著迷,不是嗎?

? 這里使用的是getDeclaredFields()。

private void printDeclaredFields(String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {System.out.println(field);}} catch(ClassNotFoundException e) {e.printStackTrace();}}

4.輸出一個類的所有public方法

? 這里與之前的getFields()類似只能對外可見的,即修飾符為public的方法。同樣,這里也是可以獲得父類的public方法。

private void printMethods(String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Method[] methods = clazz.getMethods();for (Method method : methods) {System.out.println(method);}} catch(ClassNotFoundException e) {e.printStackTrace();}}

5.輸出一個類的所有成員方法

private void printDeclaredMethods(String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println(method);}} catch(ClassNotFoundException e) {e.printStackTrace();}}

6.調(diào)用類里面的成員函數(shù)

? 這里我先假設(shè)測試類中有一個sayHello方法,如下:

public void sayHello(String from) {System.out.println("Hello from " + from); }

? 下面就可以通過getMethod()方法來反射獲得這個sayHello方法。getMethod()中第一個參數(shù)為方法名,這里即是"sayHello",后面的參數(shù)是可變量參數(shù),是可以填寫0個或是多個的,值為被反射的方法中的參數(shù)類型。這里即是String.class。

? 然后再調(diào)用invoke()方法,invoke()的第一個參數(shù)為被反射的對象,后面是向sayHello()方法中傳遞的數(shù)據(jù)。具體過程如下:

private void callMethod(Object o, String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Method method = clazz.getMethod("sayHello", String.class);method.invoke(o, TestReflect.class.getSimpleName());} catch(Exception e) {e.printStackTrace();}}

7.生成一個不能new的對象

? 可以看到上面的操作過程,都有一個前提,就是我們已經(jīng)有了這個對象。那如果我們之前沒有這個對象呢?或者說,我們不能顯式地獲得這個對象。這一點在學(xué)習(xí)單例模式的時候,就知道其實很好獲得,只要把重寫默認的構(gòu)造方法,并把這個構(gòu)造方法的修飾符修改為private即可。如下:

private PrivateClass() { }

? 這里有一點比較特殊,就是這里使用的類或是方法都是私有的。我們不能直接去使用他們,在使用他們之前,需要設(shè)置其可訪問性為true。具體操作過程如下:

private void newPrivateClass(String clazzName) {try {Class<?> clazz = Class.forName(clazzName);Constructor<?> constructor = clazz.getDeclaredConstructor();constructor.setAccessible(true);PrivateClass privateClass = (PrivateClass)constructor.newInstance();Method method = clazz.getDeclaredMethod("sayHello");method.setAccessible(true);method.invoke(privateClass);} catch (Exception e) {e.printStackTrace();}}

GitHub源碼連接:

https://github.com/William-Hai/TestReflect

總結(jié)

以上是生活随笔為你收集整理的Java反射机制浅析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。