为什么this.super()在Java中不可行?

时间:2019-06-21 18:24:01

标签: java constructor this super

在下面的示例中,如果我创建一个名为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显式声明它吗?

3 个答案:

答案 0 :(得分:7)

尽管通过调用onAction来调用超类构造函数看起来像是常规方法调用,但该语法实际上与典型方法调用不同,并且不受相同规则的约束。例如:

  1. 您只能在构造函数中使用super(args)
  2. 您只能将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有一个内部类KFoo试图继承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

更多信息