8

有人可以解释为什么它在 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>

它编译。

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

4

1 回答 1

10

我真的不知道为什么Java 6Java 7之间的行为会发生变化(您是否使用其他编译器验证过这一点?javac与 Eclipse 编译器与任何 IDEA 使用的?)。

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

通过 using ScheduledFuture,您使用的是原始类型,这意味着在您的类中几乎忽略了所有泛型的出现。这意味着您现在正在实施Comparable(并且不再实施Comparable<Delayed>,这反过来意味着您需要实施compareTo(Object)(删除Comparable<Delayed>.compareTo()),但您实施compareTo(Delayed).

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

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

于 2013-07-29T10:51:18.707 回答