为什么 `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.
.
简直是多余的
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 anExpressionName
(你的以主表达式开头)
语法如下:
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
inClassOrInterfaceTypeToInstantiate
must unambiguously denote an inner class that is accessible, non-final, not an enum type, and a member of the compile-time type of thePrimary
expression or theExpressionName
. Otherwise, a compile-time error occurs.
因此,它必须是表达式类型的成员。因此,没有必要限定它,因为它不能是 但 Outer
.
必须指定 Outer.
.