Does the Dosen't Reflection API violate the very goal of data encapsulation?

Most recently, I came across the Reflection API, and to my surprise, we can access and even modify 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 result.

 Variable is name and value is John Variable is name and value is Sam 

We say that Java is an object-oriented language, and its main functions are data encapsulation, inheritance, polymorphism, etc. Is the reflection API the very goal of data encapsulation? Why should we use the Reflection API? I read on some sites that it can be used for testing, but, according to me, the modules are tested, and this can be done easily using JUnit test cases. So can someone explain why we have such a hack?

+6
source share
4 answers

Is the reflection API the very goal of data encapsulation?

Yes and no.

  • Yes, some reflection API applications can disrupt data encapsulation.
  • No, not all uses of the reflection API really violate data encapsulation. Indeed, a wise programmer only breaks encapsulation through the reflection API when there is good reason for this.
  • No, the reflection API does not change the purpose of data encapsulation. The purpose of data encapsulation remains the same ... even if someone intentionally breaks it.

Why should we use the Reflection API?

There are many uses of reflection that DO NOT destroy encapsulation; for example, using reflection to find out what types of a super class are, what annotations it has, what members it has, invoke available methods and constructors, read and update available fields, etc.

And there are situations when it is permissible (to one degree or another) to use varieties of reflection of encapsulation:

  • You may need to look inside the encapsulated type (for example, access / change private fields) as the easiest way (or the only way) to implement certain unit tests.

  • Some forms of dependency injection (aka IoC), Serialization, and Persistence are associated with access and / or updating private fields.

  • Very often you need to break encapsulation in order to get around an error in some class that you cannot fix.

I read on some sites that it can be used for testing, but according to my modules it has been tested, and this can be done easily using JUnit test cases. So can someone explain why we have such a hack?

It depends on the design of your class. The class to be tested will either be tested without the need to access the "private" state, or it will expose this state (for example, protected getters) to allow testing. If the class does not, then the JUnit test may need reflection to look inside the abstraction.

This is undesirable (IMO), but if you are writing unit tests for a class that someone has written, and you cannot โ€œtuneโ€ the API to increase your test ability, 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 is to break it or ignore it.

Note that not all OO languages โ€‹โ€‹support strong data encapsulation, as Java does. For example, Python and Javascript are undeniably OO languages, but also make it easy for one class to access and change the state of objects of another class ... or even change other class behavior. Strong data abstraction is not central to all views on object-oriented tools.

+9
source

Yes, this violates the concept of OO. However, it does not violate any Java security model. If necessary, it can be managed by the Java Security Manager. Java reflection itself is a useful thing. It is used in annotations and IOCs, which are very useful concepts with the ability to process classes at runtime.

0
source

You cannot mix Encapsulation , Polymorphism with reflection.

Reflection has a completely different purpose. With reflection, you can dynamically create types and execute it. You can dynamically access class members at runtime.


For example, I recently used reflection to run Plugins in my application. I loaded the dll from a specific directory and then created the class object via reflection, dropping it to the common interface.

0
source

Is the reflection API the very goal of data encapsulation?

Don't get too obsessed with the rules. There are times when it is useful to break them.

Reflextion is very helpful. Take, for example, my code for registering changes so that I can register them in the database:

 public static void log(String userID, Object bOld, Object bNew) throws IntrospectionException, IllegalAccessException, InvocationTargetException { String res = "";//String to hold the change record boolean changed = false; try { if(bOld != null){ //if this is an update BeanInfo beanInfo = Introspector.getBeanInfo(bOld.getClass()); res = bOld.getClass().getSimpleName() + " - "; //loop and compare old values with new values and add them to our string if they are changed for (PropertyDescriptor prop : beanInfo.getPropertyDescriptors()) { Method getter = prop.getReadMethod(); Object vOld = getter.invoke(bOld); //old value Object vNew = getter.invoke(bNew); //new value if (vOld == vNew || (vOld != null && vOld.equals(vNew))) { continue; } changed = true; res = res + "(" + prop.getName() + ", " + vOld + ", " + vNew + ")"; } } 

It is much easier to do so. If I used getters, I would have to write a separate method for each class and change it every time I add a new field. With reflection, I can simply write one method to handle all my classes. I write about my change registration method here

0
source

Source: https://habr.com/ru/post/945361/


All Articles