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:
Code 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:
Code 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();}}}
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
To do: We need to add some explanation of what is going on here.
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].