Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't this.super() possible in java?

In the following example if I make a constructor of a class called example like so:

public class Example{

    public Example(){
        this.super();
    }

}

The above will not work because javac Example.java informs about following compilation error:

Example.java:3: error: illegal qualifier; Object is not an inner class
        this.super();
            ^
1 error

But shouldn't it work as instead of implicitly stating this by using super(), we are explicitly stating it by using this?

like image 548
ABC123 Avatar asked Jun 08 '26 07:06

ABC123


2 Answers

Although invoking a superclass constructor by calling super(args) looks like it’s a regular method call, that syntax is actually different from a typical method call and isn’t subject to the same rules. For example:

  1. You can only use super(args) in a constructor.
  2. You can only use super(args) as the first line of a constructor.

In that sense, it probably helps to think of this not as a method call, but simply as a way of telling Java what you want to do to initialize the superclass.

Because this isn’t a typical method call, the rules for regular method calls don’t apply to it. As a result, you can’t prefix it with this. to make the receiver object explicit. There’s no fundamental reason why the Java language designers couldn’t have made this syntax legal; they just chose not to do so.

like image 78
templatetypedef Avatar answered Jun 10 '26 07:06

templatetypedef


The JLS, Section 8.8.7.1, controls the specifications for explicit constructor invocations. It is possible in the grammar to specify this.super().

Primary . [TypeArguments] super ( [ArgumentList] ) ;

And a "Primary" expression can be this. Therefore, this.super() is a legal expression according to the grammar of the Java language, but that's not enough. It's not legal according to the semantics of such an expression.

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.

The semantics indicate that here, this is attempting to indicate an enclosing instance, not the current object instance. The compiler error you get isn't the clearest, but here, this is attempting to reference the enclosing class of the superclass, but Object does not have an enclosing class.

public class J {
    public J() {
        this.super();
    }
}

J.java:17: error: illegal qualifier; Object is not an inner class
        this.super();
            ^
1 error

Let's attempt to use this as an enclosing instance. Class J has an inner class K, and Foo attempts to subclass J.K.

class J {
    public J() { }
    public class K {}
}
class Foo extends J.K {
    public Foo() {
        this.super();
    }
}

The error now is:

J.java:21: error: cannot reference this before supertype constructor has been called
            this.super();
            ^
1 error

I can only get it to work with a primary expression other than this.

class Foo extends J.K {
    public Foo() {
        new J().super();
    }
}

A semantics error, not a grammar error, prevents you from using this.super().

like image 36
rgettman Avatar answered Jun 10 '26 06:06

rgettman