Java 7但不是Java 6:"不是抽象的,不会覆盖抽象方法"

Tho*_*son 8 java generics type-erasure raw-types java-7

有人可以解释为什么这会在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; }
}
Run Code Online (Sandbox Code Playgroud)

为了您的信息,此类中的方法是在编写类声明后由IntelliJ生成的.

该错误消息表明编译器要求该类声明一个compareTo方法,该方法接受一个Object类型化参数,该类接受一个Delayed.但是,ScheduledFuture接口被定义为扩展,而接口Delayed又扩展Comparable<Delayed>到我,所有东西似乎都是有序的.

如果我只是将声明更改为

private class Example implements ScheduledFuture<Object>
Run Code Online (Sandbox Code Playgroud)

它汇编.

我猜这与某种类型的擦除有关,但我无法解释它以满足自己.

Joa*_*uer 10

我真的不知道为什么Java 6Java 7之间的行为发生了变化(您是否已经使用其他编译器验证了这一点?javac与Eclipse编译器相比,IDEA使用的是什么?).

但我可以告诉你,为什么compareTo(Delayed)执行compareTo(Object),当你扩展ScheduledFuture:

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

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

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