儘管我們通常認為透過JAVA的反射機制來存取其它類別的私有欄位和私有方法是可行的,其實並沒有那麼困難。
註:只有在單獨的JAVA程式中執行該程式碼才有效,就像你做一些單元測試或常規的程式。如果你嘗試在JAVA APPLET內使用該方法,你需要稍微修改SecurityManager。但是,因為你不是經常需要與它打交道,這裡也就不再贅述了。
這裡是本次內容的列表:
1.訪問私有字段。
2.訪問私有方法。
訪問私有字段:
為了存取私有字段,你需要呼叫Class.getDeclaredField(String name)或Class.getDeclaredFields()方法。方法Class.getField(String name)和Class.getFields()只是傳回共有的字段,所以它們都無法發揮作用。這裡有一個例子,該例子中有一個包含私有欄位的類,在該類下面有透過反射來存取私有欄位的程式碼。
複製代碼代碼如下:
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")。正是這個呼叫這個方法傳回了私有欄位。這個方法僅根據指定的類別傳回字段,不會傳回父類別申明的字段。
另外仔細觀察加粗的語句。透過呼叫Field.setAccessible(true),你關掉了對於這個指定欄位實例的存取檢查,僅對反射有效。現在你能存取它了,不管它是私有的,保護的或是預設的(default),即時呼叫者並不在該範圍。你仍然不能透過常規方法存取該字段,因為編譯器不允許。
存取私有方法<BR>為了存取一個私有方法,你需要呼叫Class.getDeclaredMethod(String name,Class[] parameterTypes)或Class.getDeclaredMethods()方法。方法Class.getMethod(String name,Class[] parameterTypes)和Class.getMethods()只會傳回公有方法,所以它們不會發揮作用。下面是一個簡單的例子,該例子中有一個擁有私有方法的類,類別下面是透過反射機制存取私有方法的程式碼。
複製代碼代碼如下:
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",該值剛好是私有方法的回傳值。