Java 7, but not Java 6: "is not abstract and does not cancel the abstract method"

Can someone explain why this compiles in JDK 1.6, but not in JDK 1.7, from where I get the error message:

java: the example is not abstract and does not override the abstract compareTo method (java.lang.Object) in java.lang.Comparable?

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; } } 

For your information, the methods of this class are generated by IntelliJ after writing only the class declaration.

The error message indicates that the compiler requires the class to declare a compareTo method that accepts a typed Object parameter, and this class accepts Delayed . However, the ScheduledFuture interface is defined as a Delayed extension, which, in turn, extends Comparable<Delayed> , so it seems to me that everything is in order.

If I just changed the ad to

 private class Example implements ScheduledFuture<Object> 

it compiles.

I suppose this has something to do with type erasure, but I can't explain it to satisfy myself.

+8
java generics raw-types java-7 type-erasure
source share
1 answer

I really don't know why the behavior changes between Java 6 and Java 7 (have you confirmed that with other compilers? javac versus Eclipse compiler and one that uses IDEA?).

But I can tell you why compareTo(Delayed) does not implement compareTo(Object) when extending ScheduledFuture :

Using ScheduledFuture , you are using a raw type , which means that all generic incidents are largely ignored in your class. This means that you are now implementing Comparable (and no longer Comparable<Delayed> ), which in turn means that you need to implement compareTo(Object) (erasing Comparable<Delayed>.compareTo() ), but you are implementing compareTo(Delayed) .

Remember: Raw types mean only for backward compatibility. Avoid them in the new code at all costs, they do unpleasant things!

When you change the extends clause to ScheduledFuture<Object> , you “abandon” the generic system, and the compiler finally realizes (that is, “allowed to implement”) that your compareTo(Delayed) is actually the correct implementation of the Comparable<Delayed> interface Comparable<Delayed> .

+10
source share

All Articles