Java Programming/Reflection/Accessing Private Features with Reflection

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search
Navigate Reflection topic:

All features of a class can be obtained via reflection, including access to private methods & variables. But not always see [1]

Let us look at the following example, Secret.java:

public class Secret {

  private String secretCode = "It's a secret";

  private String getSecretCode(){
    return secretCode;     
  }
}

Although the field and method are marked private, the following class shows that it is possible to access the private features of a class:

import java.lang.reflect.Field; 
import java.lang.reflect.Method; 

public class Hacker {
 
  private static final Object[] EMPTY = {};

  public void reflect() throws Exception {
    Secret instance = new Secret();
    Class secretClass = instance.getClass();

    // Print all the method names & execution result
    Method methods[] = secretClass.getDeclaredMethods(); 
    System.out.println("Access all the methods"); 
    for (int i = 0; i < methods.length; i++) { 
       System.out.println("Method Name: " + methods[i].getName());
       System.out.println("Return type: " + methods[i].getReturnType());
       methods[i].setAccessible(true);
       System.out.println(methods[i].invoke(instance, EMPTY) + "\n");
    }

    //  Print all the field names & values
    Field fields[] = secretClass.getDeclaredFields();
    System.out.println("Access all the fields");
    for (int i = 0; i < fields.length; i++){ 
       System.out.println("Field Name: " + fields[i].getName()); 
       fields[i].setAccessible(true); 
       System.out.println(fields[i].get(instance) + "\n"); 
    }
 }

 public static void main(String[] args){

   Hacker newHacker = new Hacker();
 
   try { 
     newHacker.reflect();
   }
   catch (Exception e) {
     e.printStackTrace();
   }
 }
}

(Fix this to not use throws Exception; it is not a good programming practice and does not belong in a Java text. --djb 00:24, 14 March 2006 (UTC))

Output:

Access all the methods
Method Name: getSecretCode
Return type: class java.lang.String
It's a secret
Access all the fields
Field Name: secretCode
It's a secret

(We need to add some explanation of what is going on here. --djb 00:24, 14 March 2006 (UTC))

[edit] JUnit - Test Private methods

JUnit's are unit test cases, used to test the Java programs. Now you know how to test a private method using Reflection in JUnit.

(This also needs some elaboration. --djb 00:24, 14 March 2006 (UTC))

Note: It's worth adding that testing private members is a very bad habit. Unit tests are there to check behavior, not implementation. However, there are cases where you want to make sure a class exhibited the right behavior while not making the fields that need checking to assert that public (as it's generally considered bad practice to create accessors to a class just for the sake of a unit test). There's also cases when you can greatly simplify a test case by using reflection to test all smaller private methods (and their various branches), then test the main function.