Very recently I came across the Reflection API and to my surprise we can access and even alter the private variables.I tried the following code
import java.lang.reflect.Field;
public class SomeClass{
private String name = "John";
}
public class Test{
public static void main(String args[]) throws Exception {
SomeClass myClass = new SomeClass();
Field fs = myClass.getClass().getDeclaredField("name");
fs.setAccessible(true);
System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));
fs.set(myClass, "Sam");
System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));
}
}
and I got the following output.
Variable is name and value is John
Variable is name and value is Sam
We say Java is an Object oriented language and it's main features are Data Encapsulation, Inheritance, Polymorphism.. etc. Isn't the reflection API changing the very purpose of Data Encapsulation? Why do we have to use Reflection API? I read in some sites that it can be used for testing purpose but according to me modules are tested and that can be done easily using JUnit test cases. So can anyone explain why do we have such a hack?
Reflection is a tool. You may use it to break encapsulation, when it gives you more than it takes away.
Cons: Using reflection, one can break the principles of encapsulation. It is possible to access the private methods and fields of a class using reflection.
Encapsulation is a way to restrict the direct access to some components of an object, so users cannot access state values for all of the variables of a particular object. Encapsulation can be used to hide both data members and data functions or methods associated with an instantiated class or object.
Reflection API in Java is used to manipulate class and its members which include fields, methods, constructor, etc. at runtime. One advantage of reflection API in Java is, it can manipulate private members of the class too.
It's very bad because it ties your UI to your method names, which should be completely unrelated. Making an seemingly innocent change later on can have unexpected disastrous consequences. Using reflection is not a bad practice. Doing this sort of thing is a bad practice.
Isn't the reflection API changing the very purpose of Data Encapsulation?
Yes and no.
Why do we have to use Reflection API?
There are many uses of reflection that DO NOT break encapsulation; e.g. using reflection to find out what super types a class has, what annotations it has, what members it has, to invoke accessible methods and constructors, read and update accessible fields and so on.
And there are situations where is is acceptable (to varying degrees) to use the encapsulation breaking varieties of reflection:
You might need to look inside an encapsulated type (e.g. access / modify private fields) as the simplest way (or only way) to implement certain unit tests.
Some forms of Dependency Injection (aka IoC), Serialization and Persistence entail accessing and/or updating private fields.
Very occasionally, you need to break encapsulation to work around a bug in some class that you cannot fix.
I read in some sites that it can be used for testing purpose but according to me modules are tested and that can be done easily using JUnit test cases. So can anyone explain why do we have such a hack?
That depends on the design of your class. A class that is designed to be testable will either be testable without the need to access "private" state, or will expose that state (e.g. protected
getters) to allow testing. If the class doesn't do this, then a JUnit test may need to use reflection to look inside the abstraction.
This is not desirable (IMO), but if you are writing unit tests for a class that someone wrote, and you can't "tweak" the APIs to improve testability, then you may have to choose between using reflection or not testing at all.
The bottom line is that data encapsulation is an ideal that we strive to achieve (in Java), but there are situations where the pragmatically correct thing to do is to break it or ignore it.
Note that not all OO languages support strong data encapsulation like Java does. For example, Python and Javascript are both unarguably OO languages, yet both make it easy for one class to access and modify the state of objects of another class ... or even change the other classes behaviour. Strong data abstraction is not central to everyone's view of what Object-Oriented means.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With