Jump to content

Accessing Private Features with Reflection

50% developed
From Wikibooks, open books for an open world

Navigate Reflection topic: v  d  e )

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 codeCode listing 10.3: Secret.java
publicclassSecret{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 codeCode listing 10.4: Hacker.java
importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;importjava.lang.reflect.Method;publicclassHacker{privatestaticfinalObject[]EMPTY={};publicvoidreflect()throwsIllegalAccessException,IllegalArgumentException,InvocationTargetException{Secretinstance=newSecret();Class<?>secretClass=instance.getClass();// Print all the method names & execution resultMethodmethods[]=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 & valuesFieldfields[]=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 outputConsole 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

close