根据JLS,“T.super”是法律表达吗?

2022-09-02 13:35:44

请考虑以下一组表达式:

class T {{
/*1*/   Object o = T.super; // error: '.' expected
/*2*/   o.toString();
}}

尝试编译此命令将失败,并显示错误:/*1*/

error: '.' expected
    o = T.super;
               ^

使用OpenJDK 1.8.0(Ubuntu)Oracle JDK 1.8(Windows)时

但是,Eclipse 4.5.0(Mars)编译它没有任何错误,它会导致:

class T {
    T();
     0  aload_0 [this]
     1  invokespecial java.lang.Object() [8] // super()
     4  aload_0 [this]
     5  astore_1 [o]  // o = T.super
     7  invokevirtual java.lang.Object.toString() : java.lang.String [10]
    10  pop           // ^-- o.toString()
    11  return
}

从这里你可以看到java代码的行(结果行)正确地将转换为(Eclipse对)的理解)存储到局部变量中。执行代码时,它会正常完成,并且该行会生成正确的结果。/*1*/5thisObjectT.supero/*2*/

到目前为止,我没有找到与Java 8语言规范相关的任何内容,即它是否合法。由于它没有明确说明这是一个合法的表达,我的猜测是这意味着它是非法的。但是,为什么Eclipse认为它是合法的呢?因此,我的问题:o = T.super;

根据JLS,法律表达是合法的吗?T.super


编辑:通过删除包装内部类来简化代码。

答案 1

不,它不是。请参阅第19章。搜索关键字将生成以下构造:super

  • 通配符边界:extends T / super T;
  • 显式构造函数调用:super(args);
  • 现场访问:[Typename.]super.field;
  • 方法调用:[Typename.]super.method();
  • 方法参考: .super::method

它编译的事实可能被认为是一个错误或语言扩展,尽管两者之间没有真正的区别。


答案 2

T.super不是一个法律表达,因为它没有意义。(带或不带显式类型)语法仅用于从超类调用方法。 不调用任何方法(如果它是合法语法),它只引用一个类实例。在您的例子中,它引用了外部实例。正确的语法是 ,它将指向外部superT.superTT.thisthis

可以像这样查看类定义(使用命名的内部类):

class Outer
{
    // Constructor Body
    {
        class Inner
        {{
            /*1*/   Outer o = Outer.super; // error: '.' expected
            /*2*/   o.toString();
        }};
        new Inner();
    }
}

引用外部类的正确方法是

Outer o = Outer.this; // valid

推荐