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インターフェイスは拡張として定義されているため、拡張されているため、すべてが順調に進んでいるように見えますDelayedComparable<Delayed>

宣言を次のように変更した場合

private class Example implements ScheduledFuture<Object>

コンパイルします。

どういうわけか型消去に関係していると推測していますが、自分自身を満足させるためにそれを本当に説明することはできません.

4

1 に答える 1

10

Java 6Java 7の間で動作が変わる理由がよくわかりません(他のコンパイラで確認しましたか? javacvs. Eclipse コンパイラと IDEA が使用するものは何ですか?)。

しかし、拡張すると実装されないcompareTo(Delayed)理由はわかります。compareTo(Object)ScheduledFuture

を使用することで、生の型ScheduledFutureを使用していることになります。つまり、ジェネリックの出現はすべて、クラス内でほとんど無視されます。つまり、現在実装していることを意味します(そして、もはやを実装する必要はありません。これは、実装する必要があることを意味します(の消去)、しかし、実装する.ComparableComparable<Delayed>compareTo(Object)Comparable<Delayed>.compareTo()compareTo(Delayed)

覚えておいてください:生の型は、下位互換性のみを目的としています。新しいコードでは絶対に避けてください。厄介なことをします。

extends句を変更してジェネリックス システムに「オプトイン」すると、コンパイラは最終的に、実際にはインターフェイスの適切な実装であることScheduledFuture<Object>を認識します (つまり、「実現することが許可されています」) 。compareTo(Delayed)Comparable<Delayed>

于 2013-07-29T10:51:18.707 に答える