【问题标题】:Java 7 but not Java 6: "is not abstract and does not override abstract method"Java 7 但不是 Java 6:“不是抽象的,也不会覆盖抽象方法”
【发布时间】:2013-07-29 10:37:12
【问题描述】:

有人能解释一下为什么它在 JDK 1.6 中编译,但在我收到错误消息的 JDK 1.7 中却没有:

java:示例不是抽象的,不会覆盖 java.lang.Comparable 中的抽象方法 compareTo(java.lang.Object)?

import java.util.concurrent.*;

public class Example implements ScheduledFuture
{
    @Override public long getDelay(TimeUnit unit){ return 0; }
    @Override public int compareTo(Delayed o) { return 0; }
    @Override public boolean cancel(boolean mayInterruptIfRunning) { return false; }
    @Override public boolean isCancelled() { return false; }
    @Override public boolean isDone() { return false; }
    @Override public Object get() throws InterruptedException, ExecutionException {  return null; }
    @Override public Object get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return null; }
}

请注意,此类中的方法是由 IntelliJ 在编写类声明后生成的。

错误信息表明编译器要求类声明一个接受Object类型参数的compareTo方法,而这个类接受Delayed。 但是,ScheduledFuture 接口被定义为扩展 Delayed,而后者又扩展了 Comparable<Delayed>,所以对我来说一切似乎都井井有条。

如果我只是将声明更改为

private class Example implements ScheduledFuture<Object>

它编译。

我猜这与类型擦除有关,但我无法真正解释它以满足自己。

【问题讨论】:

  • 我会代替你从 1.6 和 1.7 中查找 ScheduledFuture 的 javadoc 并检查发生了什么变化。
  • 发生在我身上的是,Java 6 不会阻止参数化类的原始类型继承,而 7 会

标签: java generics java-7 type-erasure raw-types


【解决方案1】:

我真的不知道为什么 Java 6Java 7 之间的行为会发生变化(你用其他编译器验证过吗?javac vs. Eclipse 编译器 vs. IDEA 使用的任何东西?)。

但我可以告诉你为什么 compareTo(Delayed) 在扩展 ScheduledFuture实现 compareTo(Object)

通过使用ScheduledFuture,您使用的是a raw type,这意味着您的类中几乎忽略了所有出现的泛型。这意味着您现在正在实现Comparable(不再是Comparable&lt;Delayed&gt;,这反过来意味着您需要实现compareTo(Object)(删除Comparable&lt;Delayed&gt;.compareTo()),但您实现了compareTo(Delayed)

记住:原始类型是为了向后兼容。不惜一切代价在新代码中避免它们,它们会做讨厌的事情!

当您将extends 子句更改为ScheduledFuture&lt;Object&gt; 时,您“选择加入”泛型系统,编译器最终意识到(即“允许实现”)您的compareTo(Delayed) 实际上是正确的实现Comparable&lt;Delayed&gt; 接口的。

【讨论】:

  • +1:这肯定是由于使用了原始类型导致的,这意味着所有的泛型都被忽略了。
  • 我只使用过 Java HotSpot 编译器,1.6.0_43 和 1.7.0_25。
  • @ThomasLarssonKron:“HotSpot”是 JVM,而不是编译器。您可能使用过那些 Java 版本中的javac
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 2015-08-28
  • 2014-06-20
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多