Java 为什么'Outer.Inner=o.new Inner();`不是'Outer.Inner=o.new Outer.Inner();'?

Java 为什么'Outer.Inner=o.new Inner();`不是'Outer.Inner=o.new Outer.Inner();'?,java,inner-classes,Java,Inner Classes,为什么 class Outer { class Inner { } } public class Demo { public static void main(String args[]) { Outer o = new Outer(); Outer.Inner inner = o.new Inner(); } } 不是 i、 e.为什么用外部类名限定内部的类型声明,而不用外部

为什么

class Outer {    
    class Inner {       

    }    
}

public class Demo {
    public static void main(String args[]) {

        Outer o = new Outer();
        Outer.Inner inner = o.new Inner();    

    }    
}
不是

i、 e.为什么用外部类名限定
内部
的类型声明,而不用外部类名限定内部类的构造函数

谢谢。

比较:

Outer.Inner inner = o.new Outer.Inner();
我们可以通过两种方式foo

(一)

(二)


因为
o
已经是类型为
Outer
的实例,所以不需要创建另一个
Outer
实例来创建
internal
实例。您列出的第二个选项意味着您正在顶层
Outer
中创建另一个名为
Outer
的内部类的实例,而该类没有,它将给出一个错误。(编辑:刚刚注意到
o.new Outer
后面没有括号,这让我觉得你可能已经理解了我第二段的推理。)

如果您的意思是
Outer.Inner()
应该是构造函数,而不仅仅是
Inner()
,那是因为
Outer.Inner()
意味着
Inner
是一个静态的内部类<从未指定代码>静态,因此您需要一个
外部
实例。

从中,您谈论的是一个限定类实例创建表达式:

限定类实例创建表达式以
Primary
表达式或
ExpressionName

(您的以主表达式开头)

语法如下所示:

ClassInstanceCreationExpression:
不合格的ClassInstanceCreationExpression
ExpressionName。不合格的ClassInstanceCreationExpression
主要的,重要的不合格的ClassInstanceCreationExpression
不合格的ClassInstanceCreationExpression:
新建[TypeArguments]类或InterfaceTypeToInstate([ArgumentList])[ClassBody]
ClassOrInterfaceTypeToInstate:
{Annotation}标识符{.{Annotation}标识符}[TypeArgumentsOrDiamond]
钻石类型:
类型参数
稍低一点,在15.9.1中,它说:

类或interfacetypetoinstate
中的
标识符
必须明确表示可访问的非最终内部类,而不是枚举类型,以及
表达式或
表达式名
的编译时类型的成员。否则,将发生编译时错误

所以,它必须是表达式类型的成员。因此,不需要限定它,因为它只能是
外部
内部的类


由于
o.
编译器已经知道要创建嵌套实例的类型,所以它允许我们在
o.new…
部分中省略它。它可以不省略吗?@Ben我不确定你说的“不能省略它”是什么意思?是否要防止编译器允许忽略它?为什么?@Pshemo我认为这只是一个尴尬的双重否定:“能包括在内吗?”这并不能回答问题。引用的
internal
class OP是一个实例类,不像
foo
方法那样是静态的,因此比较并不完全正确。“For comparison”这里没有有意义的比较。方法的语言规则与类实例创建的规则是完全不同的。我不确定“您不需要创建另一个外部实例来创建内部实例”从何而来
o.new Outer.Inner()
不会创建另一个
Outer
实例,
Outer.Inner
仅用作一个类的类型名-内部类。不,你是对的。我一开始误读了这行代码,以为它说的是
o.new Outer().Inner()
,但没有括号。那
o.new Outer().Inner()
不会编译,它必须是
o.new Outer().new Inner()
。是的,这就是我的观点。另外,您的示例也无法编译。@而且我的意思是没有
o.
比如
new Outer().new Inner()
。接得好。
Outer.Inner inner = o.new Outer.Inner();
public class Demo {
    public static void foo(){
       System.out.println("Hello world!");
    }
}
Demo.foo();  // with Demo qualifier
Demo d = new Demo();
d.foo();  // without Demo qualifier!
ClassInstanceCreationExpression:
  UnqualifiedClassInstanceCreationExpression
  ExpressionName . UnqualifiedClassInstanceCreationExpression
  Primary . UnqualifiedClassInstanceCreationExpression

UnqualifiedClassInstanceCreationExpression:
  new [TypeArguments] ClassOrInterfaceTypeToInstantiate ( [ArgumentList] ) [ClassBody]

ClassOrInterfaceTypeToInstantiate:
  {Annotation} Identifier {. {Annotation} Identifier} [TypeArgumentsOrDiamond]

TypeArgumentsOrDiamond:
  TypeArguments 
  <>