Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是';T.super';根据JLS的法律表述?_Java_Eclipse_Java 8_Super_Jls - Fatal编程技术网

Java 是';T.super';根据JLS的法律表述?

Java 是';T.super';根据JLS的法律表述?,java,eclipse,java-8,super,jls,Java,Eclipse,Java 8,Super,Jls,考虑以下一组表达式: class T {{ /*1*/ Object o = T.super; // error: '.' expected /*2*/ o.toString(); }} 试图编译此文件将在第/*1*/行失败,错误如下: error: '.' expected o = T.super; ^ 无论是使用OpenJDK1.8.0(Ubuntu)还是Oracle JDK1.8(Windows)时 但是,Eclipse4.5.0(Mars

考虑以下一组表达式:

class T {{
/*1*/   Object o = T.super; // error: '.' expected
/*2*/   o.toString();
}}
试图编译此文件将在第
/*1*/
行失败,错误如下:

error: '.' expected
    o = T.super;
               ^
无论是使用OpenJDK1.8.0(Ubuntu)还是Oracle JDK1.8(Windows)时

但是,Eclipse4.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代码的行
/*1*/
(结果的行
5
)将
这个
转换为
对象
(Eclipse对
T.super
的理解)正确地存储到局部变量
o
。执行代码时,代码正常完成,行
/*2*/
生成正确的结果

到目前为止,我没有找到任何与
o=T.super相关的东西,即是否合法。因为它没有明确说明这是一个合法的表达,我猜它的意思是它是非法的。但是,为什么Eclipse认为它是合法的呢?因此,我的问题是:

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

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

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

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

引用外部类的正确方法是

Outer o = Outer.this; // valid
不,不是。提到搜索关键字
super
会产生以下结构:

  • 通配符边界:
    扩展T
    /
    超级T
  • 显式构造函数调用:
    super(args)
  • 字段访问:
    [Typename.]super.field
  • 方法调用:
    [Typename.]super.method()
  • 方法参考:
    super::method

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

根据JLS,这是正确的。JLS规范“表单super.Identifier是指当前对象的名为Identifier的字段,但当前对象被视为当前类的超类的实例。”

基于这个超类的是超类的实例

JLS还指出,“如果当前类不是类T或T本身的内部类,则这是编译时错误。”


在您的情况下,它显然是一个内部类。你能找到eclipse中使用的Java版本吗?

接受这种语法是一个由来已久的问题,它在eclipse 4.6的里程碑5中得到了修复。

Eclise Mars 4.5.1显然也能很好地编译它。但是JavaC1.8.0_66确实失败了。我不能代表JLS说话,但是编译的代码仍然应该为
t
实例打印
toString
,如果
toString
被覆盖。仅定义“超级标识符”和“T.super.identifier”。对我来说,这意味着“T.super”没有定义(而且“super”不能是标识符,因为它是一个关键字)。所以我认为“T.super”是未定义的(因此是编译时错误)。@QPaysTaxes,它是一个初始值设定项。有时大括号是这样放置的,因此如果您没有看到它,可能很难识别。@QPaysTaxes,通常用于填充集合,顺便说一句:
newarraylist(){{add(something);}
。虽然这不是一种非常优雅的方式,因为它创建了一个不必要的匿名类,但仍然是。问题不是关于
super.Identifier
,而是关于没有标识符的表单,这是不正确的。否。因为
super.Identifier
Primary.Identifier
在语法上是不同的结构。后者实际上是对某个对象求值,然后访问该对象的成员。前者是一个特殊的。其中,
super
实际上指的是
这个
,只是成员选择算法不同。@ashrafaliwahab“super应该包含超类实例”不太一样
super
不包含超类实例,因为只有一个实例(
this
one)
super
是一个关键字,它只是告诉编译器使用来自超类的代码(取决于使用的上下文)。这只是意味着
这个
对象被解释为好像它实际上是超类的一个实例,而不考虑覆盖。但是单词“current object”指的是
这个
,而不是
超级
关键字,它是一个关键字,不是某种特殊变量。换句话说,它确实决定了当前对象的查看方式,但并不意味着它的计算结果是当前对象。是的,我搜索了整个JLS,也没有找到相关的语法。但这是否意味着它是非法的,或者只是没有具体说明?@charlie,第19章是完整的语法。如果它不在那里,它就不是有效的语法。如果它在技术上是语法允许的,但在其他章节中没有描述,那么我们可以说它是未指定的。但事实上,它不是一个有效的语言结构,“语言扩展”是一个bug。尤其是在这种情况下,因为它没有任何好处。在
WhateverType x=Outer.super的任何场景中编译,符合标准
whatevertypex=Outer.this也会做同样的事情。@Holger,我同意。即使它做了一些事情,比如使
x
以后像
super
(也就是说,确实影响了方法的分辨率),那么它将更加危险和混乱。所以当我说“bug或语言扩展”时,我本质上是指它们是不同的
Outer o = Outer.this; // valid