156. Nest-based access control via reflection

Among the features of JDK 11, we have several hotspots (changes at bytecode level). One of these hotspots is known as JEP 181, or nest-based access control (nests). Basically, the nest term defines a new access control context that allows classes that are logically part of the same code entity, but which are compiled with distinct class files, to access each other's private members without the need for compilers to insert accessibility-broadening bridge methods.

So, in other words, nests allow nested classes to be compiled to different class files that belong to the same enclosing class. These are then allowed to access each other's private classes without the use of synthetic/bridge methods.

Let's consider the following code:

public class Car {

private String type = "Dacia";

public class Engine {

private String power = "80 hp";

public void addEngine() {
System.out.println("Add engine of " + power
+ " to car of type " + type);
}
}
}

Let's run javap (the Java class file disassembler tool that allows us to analyze the bytecode) for Car.class in JDK 10. The following screenshot highlights the important part of this code:

As we can see, to access the enclosing class field, Car.type, from the Engine.addEngine() method, Java has altered the code and added a bridge package-private method known as access$000(). Mainly, this is synthetically generated and can be seen via reflection using the Method.isSynthetic() and Method.isBridge() methods.

Even if we see (or perceive) the Car (outer) and Engine (nested) classes as being in the same class, they are compiled to different files (Car.class and Car$Engine.class). Conforming to this statement, our expectations imply that the outer and the nested classes can access each other's private members.

But being in separate files, this is not possible. In order to sustain our expectations, Java adds the synthetic bridge package-private method, access$000().

However, Java 11 introduces the nests access control context, which provides support for private access within outer and nested classes. This time, the outer and nested classes are linked to two attributes and they form a nest (we say that they are nestmates). Mainly, nested classes are linked to the NestMembers attribute, while the outer class is linked to the NestHost attribute. No extra synthetic method is generated.

In the following screenshot, we can see javap being executed in JDK 11 for Car.class (notice the NestMembers attribute):

The following screenshot shows the javap output in JDK 11 for Car$Engine.class (notice the NestHost attribute):

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.3.167