10

Nested Based Access Control (JEP 181)

 2 years ago
source link: https://blog.knoldus.com/nested-based-access-control-jep-181/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Reading Time: 2 minutes

In this blog we will discuss about a new feature which is being introduced in Java 11 Nested Based Access Control. Oracle introduces JVM level support for private access of nested classes, fields etc.

Nested Based Access Control

When we have nested classes in a class, after compilation different files are created. Before Java 11 for accessing the private member of the nested class or outer class we need to use the synthetic generated accessibility-broadening bridge methods.

But in Java 11 for accessing Classes and Interfaces Oracle has introduced another access control context known as nest.

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 (Java documentation).

So by the above defination we can say that this is a Java class bytecode level change.

Lets take an example

public class Test {
    private static int x = 5;

    public static class NestedTest {
        public static void doSomething() {
            System.out.println(x);
        }
    }
}

Now compile the code which will generate two classes

javac Test.java
  1. Test.class
  2. Test$NestedTest.class

Lets see what we have in these files Before Java 11

javap -v Test.class
    static int access$000();
    descriptor: ()I
    flags: (0x1008) ACC_STATIC, ACC_SYNTHETIC
    Code:
      stack=1, locals=0, args_size=0
         0: getstatic     #1                  // Field x:I
         3: ireturn
      LineNumberTable:
        line 1: 0
javap -v  'Test$NestedTest.class'
 public static void doSomething();
    descriptor: ()V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: invokestatic  #3                  // Method Test.access$000:()I
         6: invokevirtual #4                  // Method java/io/PrintStream.println:(I)V
         9: return
      LineNumberTable:
        line 6: 0
        line 7: 9

Here we can see when we want to access the private field x from the NestedTest.doSomething() a bridge package-private method access$000() is syntactically generated. This is just because after compilation two different compiles files are generated one for outer class and one for inner class. So to access each others private members we need some access control mechanism.

Java 11 introduced JVM level support for private access classes using two new terms “NestMembers” and “NestHost”.”NestMembers” corresponds to nested classes and “NestHost” corresponds to the enclosing outer class. From Java 11 onwards we use these terms for bridging to use the private member of a class as well.

Lets see what we have in these files After Java 11

javap -v Test.class
SourceFile: "Test.java"
NestMembers:
  Test$NestedTest
InnerClasses:
  public static #6= #5 of #3;             // NestedTest=class Test$NestedTest of class Test
javap -v  'Test$NestedTest.class'
SourceFile: "Test.java"
NestHost: class Test
InnerClasses:
  public static #23= #5 of #15;           // NestedTest=class Test$NestedTest of class Test

Here we can see that in the compiled file we have NestHost and NestMembers which helped us to access the private members as it does not effect the end user but helps at a JVM level.

Hope this blog will help you.

Happy Coding !!!

References:-


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK