Indicates that a method declaration is intended to override a method declaration in a superclass. If a method is annotated with this annotation type but does not override a superclass method, compilers are required to generate an error message.
There are a few subtle points that may escape the casual reader:
There are a few surprising consequences of this:
abstract class C1 {
public abstract void m();
}
class C2 extends C1 {
@Override
public void m() {}
}
Although the method C2.m implements the method C1.m, it also overrides it. So this is OK according to the current specification and javac accepts it. The next example is even more convoluted:
public interface Test {
void m();
}
abstract class A implements Test {
// m() is inherited from Test
}
class B extends A {
@Override
public void m() {}
}
This is also legal since m is a member of the abstract class A, B.m is overriding (and implementing) a method in a superclass. However, javac fails to accept this program.
So thought about it and came up with this specification:
Indicates that a method declaration is intended to override a method declaration in a supertype. If a method is annotated with this annotation type but does not override a supertype method, compilers are required to generate an error message
However, this doesn't work as you would expect: although override and implements are not mutually exclusive, override is not a "superset" of implements:
interface A {
void m();
}
class B implements A {
public void m() {} // implements but doesn't override
}
Whereas:
interface A {
void m();
}
interface B extends A {
void m(); // overrides but doesn't implement
}
Confused? Then you're getting there ;-)
So we tried this one:
Indicates that a method declaration is intended to override a method declaration in a supertype. If a method is annotated with this annotation type but does not override or implement a supertype method, compilers are required to generate an error message
However, what about (currently accepted by javac):
interface Foo {
@Override
String toString();
}
So does Foo.toString override or implement a method in a supertype? Not really, the JLS is a bit convoluted here but basically says that although Object is a direct supertype of Foo, Foo does not inherit Object.toString because Foo itself declares a toString method...
Now what? We thought about it and came up with:
Indicates that a method declaration is intended to override a method declaration in a supertype. If a method is annotated with this annotation type but is not in fact override-equivalent to any method declared in a supertype, compilers are required to generate an error message.
So how is this different? Rather than relying on the definition of override or implements in the JLS we simply say what we intended to say all along: if a similar method exists in a supertype, then you may use @Override.
So then Eugene says: what about visibility. Oh boy:
Indicates that a method declaration is intended to override a method declaration in a supertype. If a method is annotated with this annotation type compilers are required to generate an error message unless either the method is override-equivalent to a [update: public or protected] method in Object, or the method does override or implement a method declared in a supertype.
I hope to have this ready for b86.
Posted by Eugene Vigdorchik on May 10, 2006 at 11:24 PM PDT #
Obviously, your proposed changes go in the other direction, allowing @Override in more places instead of less. Maybe the annotation needs an optional element to allow the programmer to be more specific.
Posted by Bas de Bakker on May 11, 2006 at 12:07 AM PDT #
Posted by Peter von der Ahe on May 11, 2006 at 12:50 AM PDT #
Posted by Eugene Vigdorchik on May 11, 2006 at 12:58 AM PDT #
Posted by Peter von der Ahe on May 11, 2006 at 01:20 AM PDT #
Posted by Peter von der Ahe on May 11, 2006 at 01:33 AM PDT #
Posted by Andrew Thompson on May 11, 2006 at 06:01 AM PDT #
Posted by Damon Hart-Davis on May 11, 2006 at 06:23 AM PDT #
Posted by Steven Coco on May 11, 2006 at 09:40 AM PDT #
interface A<T> [
Collection<? extends T> m(T t);
}
interface B extends A<CharSequence> {
@Override
List<String> m(CharSequence seq);
}
because with return type covariance and
generics, it could be not obvious.
Posted by Rémi Forax on May 12, 2006 at 02:41 AM PDT #
Hi.
I think some of the spec might have been missed or something. See if you agree with these:
For the subinterface example: Section 9.4.2 unambigously says that a subinterface declaring an override-equivalent method overrides that method.
For the class implements interface example -- being that it implements but does not override -- I think this is a misunderstanding of the spirit of the spec. Section 8.4.8 says: "Moreover, if m1 is not abstract, then m1 is said to implement any and all declarations that it overrides." Taken even on its own, but also with the start of that section, saying "a class inherits all methods from superclasses and superinterfaces", this seems to simply state that this is both overridden and implemented. When the distinction is being made: "this method overrides, that method implements", it is for clarity in behavior; but not syntax.
I really don't think the strictest usage of the word is appropriate. I do not believe the specification had that intent in several places. Interfaces are really described simply as - always being abstract, and - containing all abstract methods. They are not so very far from a class.
I personally feel that it is completely valid scientifically-speaking to think of two definitions for overriding:
Again, not to suggest using rogue terms, but I feel this is accurate:
Looking at the subinterface example: Within the curly braces that contain this annotation declaration, this is the method that's going to be implemented. In other words, the class that implements B is unambiguously implementing B's method -- B has merely inherited any other methods from A, but the class extending B is contractually bound only to B. And, since the interface can refine the method signature, it falls under the same syntactic mechanism.
I think these aspects are a byproduct of the rigid viewpoint you get from single inheritance: the syntactic construct is extremely accurate when translated into the object implementation. "Java kicks butt."
Other comments and observations:
- Section 8.4.3 so happens to say: An instance method that is not abstract can be overridden by an abstract method. And it's the case that all interfaces implement an abstract method with the same signature as visible methods in Object. So to me this all means the an interface "overrides" toString if it is declared there.
- Notice that it is possible to modify the imnplementation of Object, and still the above interface requires any implementation to provide a body somewhere for that method. So again from the syntactic viewpoint, if I am declaring this signature, I really do mean it -- I am overriding any other occurrance that so happens to exist.
- No matter which of these options is chosen, in the end it is possible to compile legally and then have the dependent implementation change in such a way that the depending classes will no longer compile.
- The annotation is a modifier, and it can only be constructed with compile-time constants, so again I say it is very much in the syntactic realm.
Hopefully this is somewhat helpful. Are there any comments on any of this?
Thanks again, and best regards,
Steven.
Posted by Steven Coco on May 12, 2006 at 08:09 AM PDT #
Posted by Steven Coco on May 12, 2006 at 09:45 AM PDT #
Posted by Peter von der Ahe on May 12, 2006 at 09:46 AM PDT #
[Forum posting woes...]
Sorry: section 9.4.1 on the above:
http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.4.1
Yes?
Regards,
Steven.
Posted by Steven Coco on May 12, 2006 at 09:49 AM PDT #
Posted by Peter von der Ahe on May 12, 2006 at 10:10 AM PDT #
Apology:
Hello Peter, and anyone else reading. I have to post an apology for my lengthy comment above. I did actually somehow mis-read Peter's blog entry: I was commenting there on things that I now see do not in fact appear in the entry. Everything Peter wrote just makes fine sense; and my comment is not really pertinent actually.
My Sincere aplogies to Peter.
- Steev Coco.
Posted by Steven Coco on May 12, 2006 at 01:53 PM PDT #
P.S.:
For sure: my very off-base musings are all my own concoction also. Sorry about all that. That is all.
Steven.
Posted by Steven Coco on May 12, 2006 at 01:58 PM PDT #
Posted by Manabu Nakamura on July 23, 2006 at 09:22 PM PDT #
Posted by Peter von der Ahe on July 23, 2006 at 09:56 PM PDT #
interface Foo {
/** do something */ void do();
}
class Bar implements Foo {
/** {@inheritDoc} */ public void do();
}
If you check for well-formed Javadoc, your @inheritDoc will complain if Bar.do() doesn't implement/override Foo.do().
Posted by Mick Killianey on April 24, 2007 at 09:42 AM PDT #