为什么 this.super() 在 java 中不可能?
Why isn't this.super() possible in java?
在下面的示例中,如果我创建一个 class 调用示例的构造函数,如下所示:
public class Example{
public Example(){
this.super();
}
}
以上将不起作用,因为 javac Example.java
通知以下编译错误:
Example.java:3: error: illegal qualifier; Object is not an inner class
this.super();
^
1 error
但它不应该像使用 super()
隐式声明 this
那样工作,我们使用 this
明确声明它吗?
在Java中classes是自上而下初始化的。因此,如果您创建一个扩展对象的 class,它会调用对象的构造函数,然后调用您的 class 的构造函数。
这也是你在调用super之前不能初始化任何字段的原因,你的class还没有创建。 this
没有引用任何东西,因为尚未构建对象的模板。
https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5
更多信息
虽然通过调用 super(args)
来调用超类构造函数看起来像是常规方法调用,但该语法实际上与典型的方法调用不同,并且不受相同规则的约束。例如:
- 您只能在构造函数中使用
super(args)
。
- 您只能使用
super(args)
作为构造函数的第一行。
从这个意义上说,这可能有助于将其视为方法调用,而不是将其视为一种告诉 Java 您想如何初始化超类的方式。
因为这不是典型的方法调用,所以常规方法调用的规则不适用于它。因此,您不能在其前面加上 this.
来使接收者对象显式化。 Java 语言设计者没有让这种语法合法化的根本原因;他们只是选择不这样做。
JLS, Section 8.8.7.1 控制显式构造函数调用的规范。可以在语法中指定 this.super()
.
Primary . [TypeArguments] super
( [ArgumentList] ) ;
还有一个"Primary" expression can be this
。因此,根据 Java 语言的 语法 ,this.super()
是一个合法的表达式,但这还不够。根据这种表达式的语义,这是不合法的。
Qualified superclass constructor invocations begin with a Primary expression or an ExpressionName. They allow a subclass constructor to explicitly specify the newly created object's immediately enclosing instance with respect to the direct superclass (§8.1.3). This may be necessary when the superclass is an inner class.
语义表明,this
试图指示封闭实例,而不是当前对象实例。您得到的编译器错误不是最清楚的,但是在这里,this
试图引用 superclass 的封闭 class,但是 Object
没有封闭class.
public class J {
public J() {
this.super();
}
}
J.java:17: error: illegal qualifier; Object is not an inner class
this.super();
^
1 error
让我们尝试使用 this
作为封闭实例。 Class J
有一个内部 class K
,并且 Foo
尝试子 class J.K
.
class J {
public J() { }
public class K {}
}
class Foo extends J.K {
public Foo() {
this.super();
}
}
现在的错误是:
J.java:21: error: cannot reference this before supertype constructor has been called
this.super();
^
1 error
我只能让它与 this
以外的主要表达式一起使用。
class Foo extends J.K {
public Foo() {
new J().super();
}
}
语义错误,而非语法错误,阻止您使用 this.super()
。
在下面的示例中,如果我创建一个 class 调用示例的构造函数,如下所示:
public class Example{
public Example(){
this.super();
}
}
以上将不起作用,因为 javac Example.java
通知以下编译错误:
Example.java:3: error: illegal qualifier; Object is not an inner class
this.super();
^
1 error
但它不应该像使用 super()
隐式声明 this
那样工作,我们使用 this
明确声明它吗?
在Java中classes是自上而下初始化的。因此,如果您创建一个扩展对象的 class,它会调用对象的构造函数,然后调用您的 class 的构造函数。
这也是你在调用super之前不能初始化任何字段的原因,你的class还没有创建。 this
没有引用任何东西,因为尚未构建对象的模板。
https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5
更多信息
虽然通过调用 super(args)
来调用超类构造函数看起来像是常规方法调用,但该语法实际上与典型的方法调用不同,并且不受相同规则的约束。例如:
- 您只能在构造函数中使用
super(args)
。 - 您只能使用
super(args)
作为构造函数的第一行。
从这个意义上说,这可能有助于将其视为方法调用,而不是将其视为一种告诉 Java 您想如何初始化超类的方式。
因为这不是典型的方法调用,所以常规方法调用的规则不适用于它。因此,您不能在其前面加上 this.
来使接收者对象显式化。 Java 语言设计者没有让这种语法合法化的根本原因;他们只是选择不这样做。
JLS, Section 8.8.7.1 控制显式构造函数调用的规范。可以在语法中指定 this.super()
.
Primary . [TypeArguments]
super
( [ArgumentList] ) ;
还有一个"Primary" expression can be this
。因此,根据 Java 语言的 语法 ,this.super()
是一个合法的表达式,但这还不够。根据这种表达式的语义,这是不合法的。
Qualified superclass constructor invocations begin with a Primary expression or an ExpressionName. They allow a subclass constructor to explicitly specify the newly created object's immediately enclosing instance with respect to the direct superclass (§8.1.3). This may be necessary when the superclass is an inner class.
语义表明,this
试图指示封闭实例,而不是当前对象实例。您得到的编译器错误不是最清楚的,但是在这里,this
试图引用 superclass 的封闭 class,但是 Object
没有封闭class.
public class J {
public J() {
this.super();
}
}
J.java:17: error: illegal qualifier; Object is not an inner class
this.super();
^
1 error
让我们尝试使用 this
作为封闭实例。 Class J
有一个内部 class K
,并且 Foo
尝试子 class J.K
.
class J {
public J() { }
public class K {}
}
class Foo extends J.K {
public Foo() {
this.super();
}
}
现在的错误是:
J.java:21: error: cannot reference this before supertype constructor has been called
this.super();
^
1 error
我只能让它与 this
以外的主要表达式一起使用。
class Foo extends J.K {
public Foo() {
new J().super();
}
}
语义错误,而非语法错误,阻止您使用 this.super()
。