Nest-Based Access Control in Java 11
Java 11 introduced nest-based access control that allows classes to access each other's private members without the need for bridge methods created by the compiler. These methods are called accessibility-broadening bridge methods and the compiler inserts these into the code during the program execution.
Before Java 11, if we have private members in our code then the compiler creates accessibility-broadening bridge methods that increase the size of the deployed applications and may lead to confusion. That's why Java improved nest-based access control.
Java 11 allows classes and interfaces to be nested within each other. These nested type can be private
fields, methods, and constructors.
Basic Example: Java 11
In this example, we are calling a private
method inside a nested class. If we execute this code using earlier versions of Java than Java 11, the compiler will create a bridge method to call the private
method, but using Java 11 there is no need of a bridge method to call private
members.
public class Main {
private void display() {
System.out.println("hello from private method");
}
class NestedMain{
void msg() {
display();
}
}
public static void main(String[] args){
Main m = new Main();
Main.NestedMain n = m.new NestedMain();
n.msg();
}
}
hello from private method
This output snippet shows after executing javap -v Main
command from the terminal and we get the following details of nest-members.
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x0009) ACC_PUBLIC, ACC_STATIC
Code:
stack=4, locals=3, args_size=1
0: new #5 // class myjavaproject/Main
3: dup
4: invokespecial #6 // Method "<init>":()V
7: astore_1
8: new #7 // class myjavaproject/Main$NestedMain
11: dup
12: aload_1
13: dup
14: invokestatic #8 // Method java/util/Objects.requireNonNull:(Ljava/lang/Object;)Ljava/lang/Object;
17: pop
18: invokespecial #9 // Method myjavaproject/Main$NestedMain."<init>":(Lmyjavaproject/Main;)V
21: astore_2
22: aload_2
23: invokevirtual #10 // Method myjavaproject/Main$NestedMain.msg:()V
26: return
LineNumberTable:
line 17: 0
line 18: 8
line 19: 22
line 21: 26
}
SourceFile: "Main.java"
NestMembers:
myjavaproject/Main$NestedMain
InnerClasses:
#12= #7 of #5; // NestedMain=class myjavaproject/Main$NestedMain of class myjavaproject/Main
Reflection API new Methods
Java added some new methods to Java Reflection API Class. We can use these methods to get information on nest-based access control.
public Class<?> getNestHost()
public boolean isNestmateOf(Class<?> c)
public Class<?>[] getNestMembers()
The getNestHost()
method is used to get the name of nest host while the isNestmateOf()
method is used to check whether a class is a nestmate.
The getNestMembers()
method returns an array of nest members including classes and interfaces.
Example: Using getNestHost()
In Java, each class is a member of exactly one nest. We can use getNestHost()
method to get the nest host of the nest.
import java.util.Arrays;
public class Main {
private void display() {
System.out.println("hello from private method");
}
class NestedMain{
void msg() {
display();
}
}
public static void main(String[] args){
Main m = new Main();
Main.NestedMain n = m.new NestedMain();
n.msg();
// Get Nest Host Name
System.out.println(Main.class.getNestHost());
// Get Nest Members
System.out.println(Arrays.toString(Main.class.getNestMembers()));
// Check whether a class is nestmateg
System.out.println(Main.class.isNestmateOf(NestedMain.class));
}
}
hello from private method
class myjavaproject.Main
[class myjavaproject.Main, class myjavaproject.Main$NestedMain]
true