Java reflection: accessing private fields and methods

來源:互聯網
上載者:User

Origin: http://tutorials.jenkov.com/java-reflection/private-fields-and-methods.html

Despite the common belief it is actually possible to access private fields and methods of other classes via Java Reflection. It is not even that difficult. This can be very handy during unit testing. This text will show you how.

Note: This only works when running the code as a standalone Java application, like you do with unit tests and regular applications. If you try to do this inside a Java Applet, you will need to fiddle around with the SecurityManager.
But, since that is not something you need to do very often, it is left out of this text so far.

Here is a list of the topics covered in this text:

  1. Accessing Private Fields
  2. Accessing Private Methods
Accessing Private Fields

To access a private field you will need to call the Class.getDeclaredField(String name) orClass.getDeclaredFields() method. The methods Class.getField(String name) andClass.getFields() methods
only return public fields, so they won't work. Here is a simple example of a class with a private field, and below that the code to access that field via Java Reflection:

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);

This code example will print out the text "fieldValue = The Private Value", which is the value of the private field privateString of the PrivateObject instance created at the beginning of the code sample.

Notice the use of the method PrivateObject.class.getDeclaredField("privateString"). It is this method call that returns the private field. This method only returns fields declared in that particular class, not fields
declared in any superclasses.

Notice the line in bold too. By calling Field.setAcessible(true) you turn off the access checks for this particular Field instance, for reflection only. Now you can access it even if it is private, protected
or package scope, even if the caller is not part of those scopes. You still can't access the field using normal code. The compiler won't allow it.



Accessing Private Methods

To access a private method you will need to call the Class.getDeclaredMethod(String name, Class[] parameterTypes) or Class.getDeclaredMethods() method. The methodsClass.getMethod(String name, Class[]
parameterTypes)
 and Class.getMethods()methods only return public methods, so they won't work. Here is a simple example of a class with a private method, and below that the code to access that method via Java Reflection:

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);

This code example will print out the text "returnValue = The Private Value", which is the value returned by the method getPrivateString() when invoked on the PrivateObject instance created at the beginning
of the code sample.

Notice the use of the methodPrivateObject.class.getDeclaredMethod("privateString"). It is this method call that returns the private method. This method only returns methods declared in that particular class, not methods
declared in any superclasses.

Notice the line in bold too. By calling Method.setAcessible(true) you turn off the access checks for this particular Method instance, for reflection only. Now you can access it even if it is private, protected
or package scope, even if the caller is not part of those scopes. You still can't access the method using normal code. The compiler won't allow it.

Author notes:
Sometimes, especially when designing a tool which accepts customizable configurations, we need to create an object whose type is determined at runtime, and invoke some methods of this object. Clearly we can not create an object this way: Type obj = new Type();
as type is unknown until runtime. Java reflection helps!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.