【譯】7. Java反射——私有欄位和私有方法

pengisgood發表於2013-09-08

原文地址:http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html

 ===========================================================================================

     儘管普遍的觀點是不能直接訪問私有欄位和私有方法的,實際上通過Java反射是可以訪問其他類的私有欄位和私有方法的。它甚至不是那麼困難。在單元測試期間很容易使用。本文將介紹你怎麼做。
     注:這個只會作用在執行獨立的Java應用程式時,如寫單元測試和常規應用。如果你嘗試在Java Applet內使用它,你需要處理好SecurityManager。但是,因為這不是你經常要做的事情,所以在本文中將不會涉及它。
    下面是本文的主題列表:

  1. Accessing Private Fields (訪問私有欄位)
  2. Accessing Private Methods (訪問私有方法)

 ===========================================================================================

  • Accessing Private Fields

     為了訪問私有欄位,你需要呼叫Class.getDeclaredField(String name)方法或者Class.getDeclaredFields()方法。Class.getField(String name)和Class.getFields()方法只會返回public的欄位,所有它們不會工作。下面是一個簡單的例子,通過Java反射去訪問一個類的私有欄位:

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)方法,關閉了對特定的Field例項的訪問檢查。現在你可以訪問它,儘管它是private,或者protected,或者是package scope,即使呼叫者不在這個範圍內。你仍然不能通過一般的程式碼去訪問這些欄位。編譯器不允許這樣幹。
 ===========================================================================================

  • Accessing Private Methods

     為了訪問私有方法,你需要呼叫Class.getDeclaredMethod(String name, Class[ ] parameterTypes)方法或者Class.getDeclaredMethods()方法。Class.getMethod(String name, Class[ ] parameterTypes)方法和Class.getMethods()只會返回共有的方法,所以它們不會工作。下面是一個簡單的程式碼示例,通過Java反射訪問一個類的私有方法:

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")。是這個方法呼叫返回的私有方法。這個方法只會返回在給定的類裡面宣告的方法,而不是在任何超類裡宣告的方法。
     注意字型加粗的一行。僅僅針對反射,通過呼叫Method.setAccessible(true)方法,關閉了對特定的Method例項的訪問檢查。現在你可以訪問它了,儘管它是private,或者protected,或者package scope,即使呼叫者不在這個範圍內。你仍然不能通過一般的程式碼訪問這些方法。編譯器不允許這樣幹。

 ========================================================================================

  • 目錄

 

 

 

  這是一個本教程到目前為止涵蓋的主題列表:     

 

 

 

  1. Java反射——引言
  2. Java反射——Class物件
  3. Java反射——建構函式
  4. Java反射——欄位
  5. Java反射——方法
  6. Java反射——Getter和Setter
  7. Java反射——私有欄位和私有方法
  8. Java反射——註解
  9. Java反射——泛型
  10. Java反射——陣列
  11. Java反射——動態代理
  12. Java反射——類的動態載入和重新載入

 

 

 

(敬請期待下一篇翻譯)

 

相關文章