What is "override-equivalence" and how is it related to @Override?

annotations, java, language-design, method-signature, overriding

Solution

The reason for this is to allow you to use the `@Override` annotation in interfaces, which do not inherit from `Object` but implicitly declare all public methods from `Object` (see JLS section 9.2 interface members). You are thus allowed to declare an interface like:

interface Bar { @Override int hashCode(); }

However, you would not be allowed to declare the following interface:

interface Quux { @Override Object clone(); }

since the `clone()` method is not implicitly declared in an interface (it is not `public`).

This is described in JLS section 9.6.3.4 @Override (the Javadoc for `@Override` still refers to an old section number)

Problem

Reading the Javadoc for the `@Override` annotation, I came across the following rule: If a method is annotated with this annotation type compilers are required to generate an error message unless at least one of the following conditions hold: - The method does override or implement a method declared in a supertype. - The method has a signature that is override-equivalent to that of any public method declared in Object. I'm clear on the first point, but I'm unsure about the second one. What does it mean by "override-equivalent"? How are public methods of `Object` special in this respect? And why is this not covered under the first criterion? Moreover, this is only true of the Java 7+ documentation. The Java 6 doc doesn't say anything about override-equivalence. Why the change? Update: After further consulting the JLS (Section 8.4.2), I found the following explanation of override-equivalence: The signature of a method `m1` is a subsignature of the signature of a method `m2` if either: - `m2` has the same signature as `m1`, or - the signature of `m1` is the same as the erasure (§4.6) of the signature of `m2`. Two method signatures `m1` and `m2` are override-equivalent iff either `m1` is a subsignature of `m2` or `m2` is a subsignature of `m1`. As far as I can tell, this answers the first question ("What does it mean?") and the third question ("Why doesn't the first condition cover this?"). If I understand correctly (please inform me if I don't!), there is only one case where two methods are override-equivalent and which doesn't fall under the first condition of the original question. This is the case when the erasure of the signature of the subclass method is the same as the signature of the superclass method, but not the other way around. The second condition of the original question, then, would only come into play when we attempt to add type parameters when attempting to "override" a public method of the `Object` class. I tried the following simple example to test this, with an unused type parameter: ``` public class Foo { @Override public <T> boolean equals(Object obj) { return true; } } ``` Of course, this class doesn't compile, because the method doesn't actually override the `equals` method and thus clashes with it. But I also still receive a compiler error for using the `@Override` annotation. Am I wrong in assuming that this example meets the second condition for `@Override` usage? Or is the compiler generating this error despite not being required to?

Original source