【问题标题】:Functional reference to Object.clone() doesn't compile对 Object.clone() 的功能引用无法编译
【发布时间】:2015-10-13 16:06:01
【问题描述】:

Compiling

import java.util.concurrent.Callable;

class Ideone
{
    Callable<?> x = super::clone;
}

使用 Oracle JDK 给出:

Main.java:6: error: incompatible types: invalid method reference
    Callable<?> x = super::clone;
                    ^
    clone() has protected access in Object

这是没有意义的,因为一个类应该能够访问其父级的受保护方法。这个表达式在 Eclipse 的编译器中运行良好。

另外,() -&gt; super.clone() 编译良好....

这是一个错误吗?

【问题讨论】:

  • this::clone 工作吗?
  • 我可以用 JDK 1.8.0_51 和 Eclipse Mars 4.5.0 重现这个。看起来像一个 Eclipse 错误。
  • 工作正常 JDK 1.8.0_60 和 Eclipse Mars
  • @billc.cn 我非常简单地阅读了 6.6.2:仅允许在子类的主体内访问受保护的成员。 此外,三个要点适用于其中指定的条件。这些要点是为了防止访问同级类中的受保护成员,super 不属于那里。所以它属于介绍性句子,因此在没有任何三个限制的情况下被允许。

标签: java lambda compiler-errors java-8


【解决方案1】:

super 实际上不是一个表达式,也没有静态类型可谈。 super.foo()this.foo() 具有相同的访问权限;只是,方法调用在字节码中的翻译方式不同,作为“超级调用”,而不是“普通调用”。

JLS 对此不是很清楚;例如在protected access 部分,没有提到super.protectedMember 表格;但显然这种形式应该在 JLS 中讨论;它应该是可访问的。 (该部分确实建议 X::mX.m 应被视为相同的 w.r.t. 访问权限)

method reference部分,措辞也含糊不清;尽管如此,super::clone 的访问方式应该与访问 super.clone() 的方式相同。

已创建错误报告:JDK-8139836: “Can't use super::x method reference when x is protected”。它目前的状态是它将在 Java 9 中得到修复。

【讨论】:

  • (请参阅我的 [comment](#comment54031785_33107500)。) 6.6.2.1 是用非常精确的语言编写的,所以我想说这个案例并不含糊:这个案例实际上是未定义的。然而,由于这个表单是实现一个有用的clone() 所必需的,我简直不敢相信它已经在规范中消失了这么久。
  • 嗯...你会说不合格的clone() 形式也是未定义的吗?也许很好理解,它相当于this.clone()。同样,在 JLS 的目标受众中,super.clone() 可能在很多方面都与编译时的this.clone() 等效。
  • 我认为,可以安全地假设,如果添加不适用,“仅允许在 C 的子类 S 的主体内访问”是唯一的限制。但说“super.foo()this.foo() 具有相同的访问权限”并不完全正确,因为当前类可以用不同的(限制较少的)访问权限覆盖 foo()
  • @Holger - 好吧,我们不是在谈论foo 的一般可访问性。我们正在讨论是否可以访问this.foo(),这是一个是非问题。 (总是是的)
  • 很明显,您的预期陈述是正确的,因为 foo() 只有在可访问的情况下才能被覆盖。不过,“拥有相同的访问权限”是一个误导性的措辞。
猜你喜欢
  • 2019-09-26
  • 1970-01-01
  • 2020-04-28
  • 2013-05-13
  • 1970-01-01
  • 2020-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多