每个内部类都需要一个封闭的实例吗?

Mar*_*nik 33 java class jls

术语内部类通常用于表示"需要封闭实例的嵌套类".但是,JLS声明如下:

8.1.3.内部类和封闭实例

[...]

内部类包括本地(§14.3),匿名(§15.9.5)和非静态成员类(§8.5).

[...]

声明在静态上下文中发生的内部类的实例没有词法封闭的实例.

也,

15.9.5.匿名类声明

[...]

匿名类始终是内部类(第8.1.3节); 它永远不会static(§8.1.1,§8.5.1).

众所周知,匿名类可以在静态上下文中声明:

class A {
  int t() { return 1; }
  static A a =  new A() { int t() { return 2; } };
}
Run Code Online (Sandbox Code Playgroud)

要尖锐地描述它,

new A() {} 是一个没有封闭实例的嵌套类,在静态上下文中定义,但它不是静态嵌套类 - 它是一个内部类.

我们是否都在日常使用中为这些条款赋予了不恰当的含义?

作为一个相关的兴趣点,这个历史规范文档将术语顶层定义为内部的反面:

作为static类成员的类和作为包成员的类都称为顶级类.它们与内部类的不同之处在于顶级类只能直接使用它自己的实例变量.

而在常见用法中,顶层被认为是嵌套的反面.

Mar*_*nik 6

从规范的角度来看,问题中提出的区别是完全合理的:

  • 内部类有一些限制,它与封闭实例的问题无关(例如,它可能没有静态成员);

  • 静态嵌套类的概念基本上只是命名空间; 这些类可能被称为顶级,以及我们通常认为的顶级类.

只是static从嵌套类声明中删除一次会做两件事:

  1. 它使类需要一个封闭的实例;
  2. 它使类内在.

我们很少将内心视为必要的限制; 我们只关注封闭的实例关注点,这更加明显.但是,从规范的角度来看,限制是一个至关重要的问题.

我们缺少的是一个需要封闭实例的类的术语.JLS没有定义这样的术语,所以我们(不知道,似乎)劫持了一个相关但实际上本质上不同的术语来表示这一点.