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

前端 未结 4 489
无人共我
无人共我 2021-01-05 01:31

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.l         


        
4条回答
  •  执念已碎
    2021-01-05 01:55

    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.

提交回复
热议问题