繁体   English   中英

为什么在 Java 16 的非静态内部类中允许使用静态方法?

[英]Why are static methods allowed inside a non-static inner class in Java 16?

我们知道可以使用外部类的实例来访问非静态内部类,因此静态方法在非静态类内部意义不大。 但是从 Java 16 开始,在非静态内部类中允许使用静态方法。

为什么这个限制首先存在? 为什么新版本允许这样做?

public class OuterClass {

    class InnerClass {
        static void printMe() {
            System.out.println("Inside inner class");
        }
    }

    public static void main(String[] args) {
        InnerClass.printMe();
    }

}

您要求对 Java 16 中的更改进行推理,因此您应该首先检查发行说明,看看它是否有什么要说的。 它确实:

JEP 395:记录 ( JDK-8246771 )
工具/javac
记录已添加到 Java 语言中。 记录是 Java 语言中的一种新类。 它们充当不可变数据的透明载体,其仪式性比普通类少。

自从嵌套类首次被引入 Java 以来,除了由常量表达式初始化的静态 final 字段外,内部的嵌套类声明已被禁止声明静态成员。 此限制适用于非静态成员类、本地类和匿名类。

JEP 384: Records (Second Preview)添加了对本地接口、枚举类和记录类的支持,所有这些都是静态定义。 这是一个广受欢迎的增强功能,允许将某些声明的范围缩小到本地上下文的编码样式。

虽然JEP 384允许静态本地类和接口,但它并没有放松对静态成员类和内部类接口的限制。 内部类可以在其方法体之一内声明静态接口,但不能作为类成员。

作为自然的下一步, JEP 395进一步放宽了嵌套限制,并允许在内部类中声明静态类、方法、字段等。

有关详细信息,请参阅JEP 395

具体推理在JEP 395中给出

内部类的静态成员

如果内部类声明显式或隐式静态成员,则当前指定为编译时错误,除非该成员是常量变量。 这意味着,例如,内部类不能声明记录类成员,因为嵌套的记录类是隐式静态的。

我们放宽了这个限制,以便允许内部类声明显式或隐式静态的成员。 特别是,这允许内部类声明一个作为记录类的静态成员。

换句话说,有必要针对特定​​情况取消对内部类静态成员的限制; 即允许在内部类中声明record类。 但他们决定借此机会取消所有情况下的限制。

这意味着设计者已经得出结论,由于技术原因,整个原始限制既不是必要的,也不是可取的。


为什么这个限制首先存在?

这是一个更难的问题。 做出这种限制的决定是在 1996 年或 1997 年初设计 Java 1.1 时做出的。 任何人都不太可能仍然准确地记住最初决定背后的原因。 因此,除非有人能找到同时代的书面资料,否则我们永远无法确定。

(Brian Goetz 在上面评论说: “......在添加嵌套时(Java 1.1),在另一个类中有多种可能的静态解释,所以这个问题被推迟了。”这当然是有道理的,但这可能是(只是)一个人对大约 25 年前发生的事情的回忆。如果是我,我不会对我从那时起的记忆有信心。除非我有同时期的会议记录、笔记等可供参考。)

这里有一些关于原始限制的理由的猜测:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM