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

Why `Outer.Inner inner = o.new Inner();` not `Outer.Inner inner = o.new Outer.Inner();`?

class Outer {    
    class Inner {       

    }    
}

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

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

    }    
}

为什么是

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

没有

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

即为什么用外部 class 名称限定 inner 的类型声明,而不用外部 class 名称限定内部 class' 构造函数?

谢谢。

比较:

public class Demo {
    public static void foo(){
       System.out.println("Hello world!");
    }
}

我们可以 foo 有两种方式:

1)

Demo.foo();  // with Demo qualifier

2)

Demo d = new Demo();
d.foo();  // without Demo qualifier!

因为 o 已经是类型 Outer 的实例,您不需要创建另一个 Outer 实例来创建 Inner 实例。您列出的第二个选项意味着您正在 top-level Outer 中创建另一个名为 Outer 的内部 class 的实例,但它不存在,并且会给出错误. (编辑:刚刚注意到 o.new Outer 之后没有括号,这让我认为您可能已经理解了我第二段的推理)。

如果您的意思是 Outer.Inner() 应该是构造函数而不仅仅是 Inner(),那是因为 Outer.Inner() 暗示 Inner 是静态内部 class。 static 从未指定,因此您需要一个 Outer 实例。

来自JLS 15.9,你说的是合格的class实例创建表达式:

Qualified class instance creation expressions begin with a Primary expression or an ExpressionName

(你的以主表达式开头)

语法如下:

ClassInstanceCreationExpression:
  UnqualifiedClassInstanceCreationExpression
  ExpressionName . UnqualifiedClassInstanceCreationExpression
  Primary . UnqualifiedClassInstanceCreationExpression

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

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

TypeArgumentsOrDiamond:
  TypeArguments 
  <>

再往下一点,在 15.9.1 中,它说:

The Identifier in ClassOrInterfaceTypeToInstantiate must unambiguously denote an inner class that is accessible, non-final, not an enum type, and a member of the compile-time type of the Primary expression or the ExpressionName. Otherwise, a compile-time error occurs.

因此,它必须是表达式类型的成员。因此,没有必要限定它,因为它不能是 Outer.

中的 class

必须指定 Outer..

简直是多余的