Can someone explain why this compiles in JDK 1.6, but not in JDK 1.7 from which I get the error message:
java: Example is not abstract and does not override abstract method compareTo(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 in this class are generated by IntelliJ after writing just the class declaration.
The error message indicates that the compiler requires that the class declare a compareTo method that takes an Object
typed parameter and this class takes a Delayed
.
However, the ScheduledFuture
interface is defined as extending Delayed
which in turn extends Comparable<Delayed>
so to me everything seems to be in order.
If I just change the declaration to
private class Example implements ScheduledFuture<Object>
it compiles.
I am guessing it has to do with type erasure somehow but I can't really explain it to satisfy myself.
Extending an abstract class If you don't, a compile time error will be generated for each abstract method (that you don't override) saying “subclass_name is not abstract and does not override abstract method abstractmethod_name in classname”.
"Is it a good practice in Java to override a non-abstract method?" Yes.
A subclass must override all abstract methods of an abstract class. However, if the subclass is declared abstract, it's not mandatory to override abstract methods.
I don't really know why the behaviour changes between Java 6 and Java 7 (have you verified that with other compilers? javac
vs. Eclipse compiler vs. whatever IDEA uses?).
But I can tell you why compareTo(Delayed)
does not implement compareTo(Object)
when you extend ScheduledFuture
:
By using ScheduledFuture
, you're using a raw type, which means that all occurances of generics are pretty much ignored in your class. That means that you're now implementing Comparable
(and no longer Comparable<Delayed>
, which in turn means that you need to implement compareTo(Object)
(the erasure of Comparable<Delayed>.compareTo()
), but you implement compareTo(Delayed)
.
Remember: Raw types are meant only for backwards compatibility. Avoid them in new code at all costs, they do nasty things!
When you change your extends
clause to ScheduledFuture<Object>
you "opt-in" to the generics system and the compiler finally realizes (i.e. "is allowed to realize") that your compareTo(Delayed)
is in fact the proper implementation of the Comparable<Delayed>
interface.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With