Java 中的 getDeclaredMethods() 方法(使用與原理)
在 Java 的反射機(jī)制中,getDeclaredMethods()
是一個(gè)非常重要的方法,它允許我們獲取類中聲明的所有方法(包括公共、私有、保護(hù)以及默認(rèn)訪問權(quán)限的方法)。通過這個(gè)方法,我們可以動(dòng)態(tài)地分析和操作類的行為,這在框架開發(fā)、測(cè)試工具以及動(dòng)態(tài)代理等場(chǎng)景中非常有用。本文將深入探討 getDeclaredMethods()
的使用方法、原理以及注意事項(xiàng),幫助你更好地理解和應(yīng)用它。
1. 什么是 getDeclaredMethods()?
getDeclaredMethods()
是 java.lang.Class
類中的一個(gè)方法,用于返回當(dāng)前類中聲明的所有方法(不包括繼承的方法)。這些方法包括:
- 公共方法(
public
) - 私有方法(
private
) - 保護(hù)方法(
protected
) - 默認(rèn)訪問權(quán)限的方法(包私有)
需要注意的是,getDeclaredMethods()
不會(huì)返回從父類或接口繼承的方法。
2. getDeclaredMethods() 的使用方法
以下是一個(gè)簡(jiǎn)單的示例,展示如何使用 getDeclaredMethods()
獲取類中聲明的所有方法:
import java.lang.reflect.Method; public class MyClass { public void publicMethod() {} private void privateMethod() {} protected void protectedMethod() {} void defaultMethod() {} public static void main(String[] args) { Class<?> clazz = MyClass.class; Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { System.out.println("Method Name: " + method.getName()); System.out.println("Modifier: " + method.getModifiers()); System.out.println("Return Type: " + method.getReturnType()); System.out.println("Parameters: " + method.getParameterCount()); System.out.println("-----"); } } }
輸出結(jié)果:
Method Name: publicMethod
Modifier: 1
Return Type: void
Parameters: 0
-----
Method Name: privateMethod
Modifier: 2
Return Type: void
Parameters: 0
-----
Method Name: protectedMethod
Modifier: 4
Return Type: void
Parameters: 0
-----
Method Name: defaultMethod
Modifier: 0
Return Type: void
Parameters: 0
-----
從輸出中可以看到,getDeclaredMethods()
成功獲取了類中聲明的所有方法,包括私有方法和保護(hù)方法。
3. getDeclaredMethods() 的原理分析
getDeclaredMethods()
的實(shí)現(xiàn)依賴于 Java 的反射機(jī)制。其核心原理如下:
類加載與元數(shù)據(jù)
Java 虛擬機(jī)(JVM)在加載類時(shí),會(huì)為每個(gè)類生成一個(gè) Class
對(duì)象,該對(duì)象包含了類的元數(shù)據(jù)(如方法、字段、構(gòu)造器等)。getDeclaredMethods()
通過訪問這些元數(shù)據(jù)來獲取類中聲明的方法。
方法信息的存儲(chǔ)
方法信息(如方法名、參數(shù)類型、返回類型、訪問修飾符等)存儲(chǔ)在 Method
對(duì)象中。getDeclaredMethods()
返回的是一個(gè) Method
數(shù)組,每個(gè) Method
對(duì)象對(duì)應(yīng)一個(gè)方法。
訪問權(quán)限的檢查
默認(rèn)情況下,getDeclaredMethods()
可以獲取所有聲明的方法,包括私有方法。但如果啟用了安全管理器(SecurityManager
),則可能會(huì)拋出 SecurityException
。
4. 與 getMethods() 的區(qū)別
getMethods()
和 getDeclaredMethods()
是 Java 反射中兩個(gè)常用的方法,它們的區(qū)別如下:
getMethods()
返回當(dāng)前類及其父類、接口中的所有公共方法(public
)。
getDeclaredMethods()
僅返回當(dāng)前類中聲明的所有方法(包括私有、保護(hù)、默認(rèn)訪問權(quán)限的方法),不包括繼承的方法。
示例:
class Parent { public void parentMethod() {} } class Child extends Parent { public void childMethod() {} private void privateMethod() {} } public class Main { public static void main(String[] args) { Class<?> clazz = Child.class; System.out.println("getMethods():"); for (Method method : clazz.getMethods()) { System.out.println(method.getName()); } System.out.println("====================================="); System.out.println("getDeclaredMethods():"); for (Method method : clazz.getDeclaredMethods()) { System.out.println(method.getName()); } } }
輸出結(jié)果:
getMethods():
childMethod
parentMethod
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll
=====================================
getDeclaredMethods():
childMethod
privateMethod
5. 實(shí)際應(yīng)用場(chǎng)景
getDeclaredMethods()
在以下場(chǎng)景中非常有用:
- 動(dòng)態(tài)代理:通過反射獲取目標(biāo)類的方法,并動(dòng)態(tài)生成代理類。
- 單元測(cè)試:測(cè)試私有方法時(shí),可以通過反射調(diào)用這些方法。
- 框架開發(fā):如 Spring 框架中,通過反射解析注解并執(zhí)行相應(yīng)邏輯。
- 代碼分析工具:分析類的方法結(jié)構(gòu),生成文檔或進(jìn)行代碼檢查。
6. 注意事項(xiàng)與常見問題
- 性能問題
反射操作比直接調(diào)用方法要慢,因此在性能敏感的場(chǎng)景中應(yīng)謹(jǐn)慎使用。
- 訪問私有方法
如果需要調(diào)用私有方法,需要先調(diào)用 method.setAccessible(true)
來繞過訪問權(quán)限檢查。
- 安全管理器
如果啟用了安全管理器,可能會(huì)限制對(duì)某些方法的訪問,導(dǎo)致 SecurityException
。
- 繼承方法的缺失
getDeclaredMethods()
不會(huì)返回繼承的方法,如果需要獲取父類方法,可以使用 getMethods()
。
7. 總結(jié)
getDeclaredMethods()
是 Java 反射機(jī)制中的一個(gè)強(qiáng)大工具,它允許我們動(dòng)態(tài)地獲取類中聲明的所有方法。在實(shí)際開發(fā)中,合理使用反射可以極大地提高代碼的靈活性和可擴(kuò)展性,但也要注意其性能開銷和安全性問題。
到此這篇關(guān)于Java 中的 getDeclaredMethods() 方法:使用與原理全攻略的文章就介紹到這了,更多相關(guān)java getDeclaredMethods() 方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
別在Java代碼里亂打日志了,這才是正確的打日志姿勢(shì)
這篇文章主要介紹了別在Java代碼里亂打日志了,這才是正確的打日志姿勢(shì),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06這么設(shè)置IDEA中的Maven,再也不用擔(dān)心依賴下載失敗了
今天給大家?guī)硪粋€(gè)IDEA中Maven設(shè)置的小技巧.這個(gè)技巧可以說非常有用,學(xué)會(huì)設(shè)置之后,再也不用擔(dān)心maven依賴下載變慢的問題,需要的朋友可以參考下2021-05-05java中FileOutputStream中文亂碼問題解決辦法
這篇文章主要介紹了java中FileOutputStream中文亂碼問題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-04-04Spring實(shí)戰(zhàn)之讓Bean獲取Spring容器操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之讓Bean獲取Spring容器操作,結(jié)合實(shí)例形式分析了Bean獲取Spring容器的相關(guān)原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2019-11-11java實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲(2)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)單五子棋小游戲的第二部分,添加游戲結(jié)束條件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01MyBatis一級(jí)與二級(jí)緩存相關(guān)配置
mybatis-plus是一個(gè)Mybatis的增強(qiáng)工具,在Mybatis的基礎(chǔ)上只做增強(qiáng)不做改變,為簡(jiǎn)化開發(fā)、提高效率而生,這篇文章帶你了解Mybatis的一級(jí)和二級(jí)緩存2023-01-01