Java 11 中基于嵌套的访问控制

原文:https://www.studytonight.com/java-11/nestbased-access-control-in-java-11

Java 11 引入了基于嵌套的访问控制,允许类访问彼此的私有成员,而不需要编译器创建的桥方法。这些方法被称为可访问性扩展桥接方法,编译器在程序执行期间将这些方法插入到代码中。

在 Java 11 之前,如果我们的代码中有私有成员,那么编译器会创建可访问性扩展的桥接方法,这会增加部署的应用的大小,并可能导致混乱。这就是为什么 Java 改进了基于嵌套的访问控制。

Java 11 允许类和接口相互嵌套。这些嵌套类型可以是private字段、方法和构造器。

基本示例:Java 11

在这个例子中,我们在一个嵌套类中调用private方法。如果我们使用比 Java 11 更早的 Java 版本执行这段代码,编译器将创建一个桥方法来调用private方法,但是使用 Java 11 不需要桥方法来调用private成员。

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();

    }   
}

你好从私法

这个输出片段显示了从终端执行javap -v Main命令后,我们得到了以下嵌套成员的细节。

 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

反射 API 新方法

Java 给 Java 反射 API 类增加了一些新的方法。我们可以使用这些方法来获取基于嵌套的访问控制的信息。

public Class<?> getNestHost()
public boolean isNestmateOf(Class<?> c)
public Class<?>[] getNestMembers()

getNestHost()方法用于获取巢宿主的名称,而isNestmateOf()方法用于检查一个类是否是巢配偶。

getNestMembers()方法返回包含类和接口的嵌套成员数组。

示例:使用getNestHost()

在 Java 中,每个类都是一个嵌套的成员。我们可以用getNestHost()的方法得到巢穴的巢穴宿主。

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));
    }   
}

你好来自私有方法 类 myjavaproject。主 【类我的 myjavaproject。Main,类 myjavaproject。Main$NestedMain] true