在下面的示例中,如果我创建一个名为example的类的构造函数,如下所示:
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
但是它不是像使用this
隐式声明super()
一样起作用,而是使用this
显式声明它吗?
答案 0 :(得分:7)
尽管通过调用onAction
来调用超类构造函数看起来像是常规方法调用,但该语法实际上与典型方法调用不同,并且不受相同规则的约束。例如:
super(args)
。super(args)
用作构造函数的第一行。从这个意义上讲,将其视为方法调用不是一种方法调用,而可能只是告诉Java初始化超类要做什么的一种方式。
由于这不是典型的方法调用,因此常规方法调用的规则不适用于该方法。因此,您不能在其前面加上super(args)
来使接收方对象明确。 Java语言设计者没有使此语法合法的根本原因没有;他们只是选择不这样做。
答案 1 :(得分:3)
JLS, Section 8.8.7.1控制显式构造函数调用的规范。语法中可以指定this.super()
。
主要。 [TypeArguments]
super
( [ArgumentList] );
还有一个"Primary" expression can be this
。因此,this.super()
是根据Java语言的语法的合法表达式,但这还不够。根据此类表达式的语义,这是不合法的。
合格的超类构造函数调用以 Primary 表达式或 ExpressionName 开头。它们允许子类构造函数相对于直接超类(第8.1.3节)显式指定新创建的对象的直接封闭实例。当超类是内部类时,这可能是必需的。
语义表明此处this
试图指示封闭实例,而不是当前对象实例。您得到的编译器错误不是最清楚的,但是在这里,this
试图引用超类的封闭类,但是Object
没有封闭类。
public class J {
public J() {
this.super();
}
}
J.java:17: error: illegal qualifier; Object is not an inner class
this.super();
^
1 error
让我们尝试使用this
作为封闭实例。类J
有一个内部类K
,Foo
试图继承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()
。
答案 2 :(得分:0)
在Java中,类是自上而下初始化的。因此,如果您创建一个扩展对象的类,则它调用对象的构造函数,然后调用您的类的构造函数。
这也是您无法在调用super之前初始化任何字段的原因,因为您的类尚未创建。 this
没有引用任何内容,因为尚未构造对象的模板。
https://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5
更多信息