Accessing Private Features with Reflection
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:
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:
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(); } } }
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
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] .
- ↑ What's the best way of unit testing private methods?, March 7, 2011
- ↑ Reflection API injected at compile-time [dead link ]
To do:
Add some exercises like the ones in Variables