📜 ⬆️ ⬇️

As I rediscovered encapsulation in java.

I have always believed that Java is a laconic and beautiful (in terms of concept) language with a clear structure that allows you to extend this structure to all sorts of frameworks, it also helps to bring order to the code of the final programmer. And, above all, I believed that java is 100% OO language! But recently I came across a code, after which I walked in the evening indignant. The code is quite simple to understand even people who are not knowledgeable in java.
Suppose we have class A in some package:

 package test; public class A { private int x = 33; public void test(){ System.out.println(x); } } 

As you can see, the x field is protected and, according to the dock from sun , this field is not visible either in subclasses A, or in the test package, or even in other packages. Therefore, we have every reason to believe that the test () method always returns the number 33. Moreover, we could use this assumption in our code, tying any logic on this.
Next, we have a class in any other package (but within the same JVM):

 package access; public class X { public void getAccess() throws Exception{ A a = new A(); Field x = a.getClass().getDeclaredField("x"); x.setAccessible(true); x.setInt(a, x.getInt(a)+1); System.out.print("protected field: "); a.test(); } } 

That's all. All our assumptions about the encapsulation and immutability of the A.x field are dispelled. The A.test () method now returns the number 34 (and if we started some logic on this, then our code is unlikely to work correctly now). And it may even seem that one of the three precepts of the PLO is broken - encapsulation. The programmer of the java.lang.reflect package is guilty of everything. This package provides features for working with objects at the program execution stage. Because Since almost all classes of this object work with dynamic structures, it works rather slowly and should be used only in exceptional cases. However, the possibility of its use remains a violation of encapsulation there.
')
Afterwards, having run with this package, I found that a special SecurityManager class is responsible for maintaining security and access, and if I run it, everything will fall into place. If our class A add a static initializer:

 public class A { static{ if(System.getSecurityManager()==null) System.setSecurityManager(new SecurityManager()); } 

That trick to the ears, which turned out in the previous example, will not pass. T.ch. everything is in order, Java is still an OO language :) The only thing for which I wrote this post is to warn (this is not a signal for action, you just need to keep this in mind too) of all Yapistians:

DEVELOPER, BDI!
If there is no SecurityManager at runtime, anyone can climb into your classroom and change anything!

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


All Articles