摘要:盡管普遍認知是,實際可以通過反射訪問其他類的私有屬性和方法。這個特性在單元測試中特別有用。注意這只能在單體應用程序中運行,比如單元測試和常規(guī)程序。注意已經(jīng)有很多關于禁用反射訪問類私有屬性的討論。調(diào)用將關閉實例的訪問權限檢查,僅用于反射。
盡管普遍認知是,實際可以通過反射訪問其他類的私有屬性和方法。它甚至并不難。這個特性在單元測試中特別有用。本文將告訴你如何做。
注意:這只能在單體Java應用程序中運行,比如單元測試和常規(guī)程序。如果你嘗試在Java Applet程序中使用,可能需要注意SecurityManager問題。但是,你并不常做這些操作,并且到目前為止已偏離了本文主題。
注意:已經(jīng)有很多關于Java9禁用反射訪問類私有屬性的討論。根據(jù)我的經(jīng)歷,在Java9依舊是可以的(訪問類私有屬性),但這可能會在Java未來版本中改變。
訪問私有屬性需要調(diào)用Class.getDeclaredField(String name)或者Class.getDeclaredFields()方法。方法Class.getField(String name) 和Class.getFields()只返回類的public方法,所以不能使用它們。下面的示例代碼是一個有私有屬性的類,再下一個是通過反射訪問私有屬性。
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } }
PrivateObject privateObject = new PrivateObject("The Private Value"); Field privateStringField = PrivateObject.class. getDeclaredField("privateString"); privateStringField.setAccessible(true); String fieldValue = (String) privateStringField.get(privateObject); System.out.println("fieldValue = " + fieldValue);
示例代碼會輸出“fieldValue = The Private Value”,它是PrivateObject實例的privateString屬性的值。
使用方法privateObject.class.getDeclaredField("privateString")時需要注意。這個方法返回私有屬性。這個方法只返回特定類定義的屬性,不包括任何超類的屬性。
另外需要注意代碼privateStringField.setAccessible(true);。調(diào)用這個方法將為特定的Field實例關閉訪問權限檢查,僅用于反射?,F(xiàn)在你可以訪問屬性,不管它是private, protected 或者package scope,即使調(diào)用方不在訪問scope內(nèi)。你依舊不能使用普通代碼訪問私有屬性,Java編譯通不過。
訪問類私有方法需要調(diào)用Class.getDeclaredMethod(String name, Class[] parameterTypes)或者Class.getDeclaredMethods()。方法Class.getMethod(String name, Class[] parameterTypes)和Class.getMethods() 只返回類的public方法,所以不能使用。下面是一個有私有方法的類和如何通過反射調(diào)用該類方法的私有代碼:
public class PrivateObject { private String privateString = null; public PrivateObject(String privateString) { this.privateString = privateString; } private String getPrivateString(){ return this.privateString; } }
PrivateObject privateObject = new PrivateObject("The Private Value"); Method privateStringMethod = PrivateObject.class. getDeclaredMethod("getPrivateString", null); privateStringMethod.setAccessible(true); String returnValue = (String) privateStringMethod.invoke(privateObject, null); System.out.println("returnValue = " + returnValue);
示例代碼會輸出"returnValue = The Private Value",這是實例PrivateObject中的方法getPrivateString()的返回值。
注意,代碼PrivateObject.class.getDeclaredMethod("privateString")。這個方法調(diào)用將返回類的私有方法。這個方法只返回類直接定義的方法,而不返回任何超類的方法。
另外需要注意代碼privateStringMethod.setAccessible(true);。調(diào)用Method.setAcessible(true)將關閉Method實例的訪問權限檢查,僅用于反射?,F(xiàn)在你可以調(diào)用方法,不論它是private, protected 或 package scope,即使調(diào)用者不在這些scopes內(nèi)。你依舊不能通過普通方法訪問類的私有方法,這會編譯不通過。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/77339.html
摘要:通過反射獲取帶參無返回值成員方法并使用設置安全檢查,訪問私有構造函數(shù)必須創(chuàng)建實例這種不行,注意和方法需要傳遞參數(shù)測試復制這個功能獲取私有方法,同樣注意和的區(qū)別賦予訪問權限調(diào)用方法。 反射 目錄介紹 1.反射概述 1.1 反射概述 1.2 獲取class文件對象的三種方式 1.3 反射常用的方法介紹 1.4 反射的定義 1.5 反射的組成 1.6 反射的作用有哪些 2.反射的...
摘要:在的反射包中提供了三個類以及來分別描述屬性方法和構造器。獲取構造器獲取方法可以看到我們可以通過一個類的對象很輕松的獲取他的屬性構造器以及方法信息。返冋一個用于描述構造器名的字符串。 想要獲取更多文章可以訪問我的博客?-?代碼無止境。 上周上班的時候解決一個需求,需要將一批數(shù)據(jù)導出到Excel。本來公司的中間件組已經(jīng)封裝好了使用POI生成Excel的工具方法,但是無奈產(chǎn)品的需求里面有個合...
閱讀 4083·2023-04-26 01:48
閱讀 3258·2021-10-13 09:40
閱讀 1739·2021-09-26 09:55
閱讀 3614·2021-08-12 13:23
閱讀 1780·2021-07-25 21:37
閱讀 3432·2019-08-30 15:53
閱讀 1393·2019-08-29 14:16
閱讀 1397·2019-08-29 12:59