Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dosen't Reflection API break the very purpose of Data encapsulation?

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?

like image 841
Aniket Thakur Avatar asked May 19 '13 13:05

Aniket Thakur


People also ask

Does reflection break encapsulation?

Reflection is a tool. You may use it to break encapsulation, when it gives you more than it takes away.

Does the reflection API of Java Break data encapsulation?

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.

What is the purpose of data encapsulation?

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.

What was the main idea of reflection API?

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.

Why we should not use reflection in Java?

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.


1 Answers

Isn't the reflection API changing the very purpose of Data Encapsulation?

Yes and no.

  • Yes, some uses of the reflection API can break data encapsulation.
  • No, not all uses of the reflection API do break data encapsulation. Indeed, a wise programmer only breaks encapsulation via the reflection API when there is a good reason to do so.
  • No, reflection API does not change the purpose of data encapsulation. The purpose of data encapsulation remains the same ... even if it someone wilfully breaks it.

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.

like image 74
Stephen C Avatar answered Oct 13 '22 01:10

Stephen C