Jump to content
Wikibooks The Free Textbook Project

Accessing Private Features with Reflection

From Wikibooks, open books for an open world

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:

Computer code Code listing 10.3: Secret.java
publicclass Secret{
privateStringsecretCode="It's a secret";

privateStringgetSecretCode(){
returnsecretCode;
}
}

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

Computer code Code listing 10.4: Hacker.java
importjava.lang.reflect.Field;
importjava.lang.reflect.InvocationTargetException;
importjava.lang.reflect.Method;

publicclass Hacker{

privatestaticfinalObject[]EMPTY={};

publicvoidreflect()throwsIllegalAccessException,IllegalArgumentException,InvocationTargetException{
Secretinstance=newSecret();
Class<?>secretClass=instance.getClass();

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

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

publicstaticvoidmain(String[]args){
HackernewHacker=newHacker();

try{
newHacker.reflect();
}catch(Exceptione){
e.printStackTrace();
}
}
}
Standard input or output Console for Code listing 10.4
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
[画像:Clipboard]

To do:
We need to add some explanation of what is going on here.


JUnit - Test Private methods

[edit | edit source ]

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. There's a long-standing debate on whether testing private members is a good habit[1] ;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 are 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. With dp4j [dead link ] it is possible to test private members without directly using the Reflection API but simply accessing them as if they were accessible from the testing method; dp4j injects the needed Reflection code at compile-time[2] .

  1. What's the best way of unit testing private methods?, March 7, 2011
  2. Reflection API injected at compile-time [dead link ]


[画像:Clipboard]

To do:
Add some exercises like the ones in Variables

AltStyle によって変換されたページ (->オリジナル) /