Accessing private fields and methods using reflection

Knoldus Inc.
3 min readApr 26, 2020

--

Reflection is a very powerful tool or API through which you can modify or examine the behavior of any class, method, or trait/interface at runtime.

And it is the reflection only through which you can access private members of a class using its object at runtime.
Sometimes you need to access the private members of a class, for example, while writing unit test cases you may need to check and validate the behavior of a private method.

class Person(name: String) {
private def greet: String = s”Hello $name !”
}
val p = new Person(“Harshit”)

In the example class Person, there is a private method named greet. If you try to access this method directly using this class’s object p, like below -

p.greet

This statement will not compile and your compiler will generate an error.

error: method greet in class Person cannot be accessed in Person

The reason is pretty straightforward because you are trying to access a private method through an object. And private access modifiers are meant to be accessible only within the class.

But as mentioned above, using reflection you can actually access the private methods of a class. And below is the snippet which makes this magic happen.

val m = p.getClass.getDeclaredMethod(“greet”)
m.setAccessible(true)
m.invoke(p)

If you run the above sample of code, then you will get the desired output.

Hello Harshit !

Now let’s see how did all this happen even via reflection.

So the first statement -

p.getClass.getDeclaredMethod(“greet”)

This statement, when executed, will return you the type java.lang.reflect.Method. The Method class as the name defines; contains all the information about a method of any class like number of parameters, parameter types, access modifier type, return type, etc.

Next statement is -

m.setAccessible(true)

With this statement, we are setting the accessible flag of the method class as true. The boolean flag named accessible in the Method class indicates that is this method accessible from the object p. A true value would allow this method to be accessible by object p via reflection.

The official documentation reads as:

Set the accessible flag for this reflected object to the indicated boolean value. A value of true indicates that the reflected object should suppress checks for Java language access control when it is used. A value of false indicates that the reflected object should enforce checks for Java language access control when it is used, with the variation noted in the class description.

If you don’t call setAccessible method as mentioned above, you would see the below exception.

java.lang.IllegalAccessException: Class can not access a member of class Person with modifiers “private”

Now the final statement, which is -

m.invoke(p)

This is the statement through which you are accessing the method m via object p through reflection. Its behavior is the same as you would call p.greet (if greet was not private). When you execute the statement, you would see the output of this private method.

So now, you have an idea of how to access private methods using reflection. But you should not be using this in your production code as it may lead to complexity and your code will be messy. Accessing private methods using reflection should only be done when you want to debug something or while writing unit test cases of private methods which are very complex and contain some valuable business logic.

There are libraries, which are using reflection to access private members.
Scalatest, the testing tool for the Scala ecosystem has a trait PrivateMethodTester which allows you to access the private methods of a class. And by mixing this trait into your test class, you can write test cases for your class/trait’s private members easily.

Knoldus-blog-footer-image

--

--

Knoldus Inc.

Group of smart Engineers with a Product mindset who partner with your business to drive competitive advantage | www.knoldus.com