天天看點

分享調用Java private方法

上周在修複bug時,發現Java類中某方法是private,且類中沒有用到,第一感覺是方法多餘。其實通過分析,發現原來Native Code會通過JNI調到此方法。這也給自己啟發,平時做Code refine時,如果方法沒有被直接調用,一定要注意是否會有反射會調用到等,否則移除後,編譯通過,但會有問題~

雖然是小文法點,但很感興趣,而且易被忽略。這兩天查了一些資料,分享下

一. Native Code調用Java類中private方法​

例如JNI開發中,C可以反射調到Java的方法,例如通過GetMethodID等API,原因解釋:

分享調用Java private方法

是以在判斷private方法在哪裡被調用時,記得多在代碼裡搜尋下,避免出現此類情況,誤認為方法沒有被使用~

參考:

1. https://stackoverflow.com/questions/12208387/can-a-native-method-call-a-private-method

2. http://journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementing/method.html

二. Java中通過反射也可以調用其他類的private方法

舉例:​

分享調用Java private方法

其中a是Test類中的private方法,通過getDeclaredMethod可以獲得目标Class中的方法(不包含父類)。能否執行private方法,取決于setAccessible API,此接口會在基類AccessObject中設定成員變量overide為true,注釋的解釋很有用,如下:

分享調用Java private方法

如overide為true,會取消Language-Level的安全檢查,如通路修飾符private的限制等。另外出于安全考慮,非此package無法通路overide變量。

參考:https://stackoverflow.com/questions/880365/any-way-to-invoke-a-private-method​

最後分享個小的tip,Android中反射相關代碼來自ojluni,如果對這個名字感到不解的話,它的意思是: OpenJDK;java.lang;java.util;java.net ;java.io 的縮寫,就是OpenJDK核心庫的意思,與Google采用OpenJDK代替原有Java API的變動有關~Thanks

                                                                                                                                     - Kevin Song

                                                                                                                                       2017.8.1