有人可以解释为什么在JDK 1.6中进行编译,而在JDK 1.7中进行编译,但从中得到错误消息:
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生成的。
错误消息表明编译器要求该类声明一个compareTo方法,该方法采用
Object
类型的参数,而此类则采用Delayed
。但是,
ScheduledFuture
接口(interface)定义为扩展Delayed
,这又扩展了Comparable<Delayed>
,因此对我来说,一切似乎都井然有序。如果我只是将声明更改为
private class Example implements ScheduledFuture<Object>
它编译。
我猜想它与某种程度上的类型擦除有关,但是我不能真正解释它来满足自己。
最佳答案
我真的不知道为什么Java 6和Java 7之间的行为会发生变化(您是否已使用其他编译器进行了验证?javac
与Eclipse编译器以及任何IDEA一起使用?)。
但是我可以告诉您,当您扩展compareTo(Delayed)
时,为什么compareTo(Object)
不能使而不是实现ScheduledFuture
:
通过使用ScheduledFuture
,您正在使用a raw type,这意味着在类中几乎忽略了泛型的所有出现。这意味着您现在正在实现Comparable
(不再是Comparable<Delayed>
,这反过来意味着您需要实现compareTo(Object)
(擦除Comparable<Delayed>.compareTo()
),但是要实现compareTo(Delayed)
。
请记住:原始类型是指,仅是,用于向后兼容。不惜一切代价避免在新代码中使用它们,它们会做讨厌的事情!
当您将extends
子句更改为ScheduledFuture<Object>
时,您“选择加入”了泛型系统,编译器最终意识到(即“被允许实现”)您的compareTo(Delayed)
实际上是Comparable<Delayed>
接口(interface)的正确实现。