RFE Standard Annotation @Override/@Implements
Hello,
using JDK 5/6 for a few months, I've just started playing with standard annotations (which by the way are not extremely well documented in the JDK docs, I had to go look at the javadoc for packagejava.lang.annotations to find them out).
I'm finding the @Override annotation quite useful, to explicitly document that a method is intended to override a superclass' method. This prevents silly mistakes, such as, mispellinghashCode() (anyone gone through that one will feel some empathy :o), but anyway it is a good clarification at the code level of the intent of a design.
However, @Override cannot be used for a method that implements a method m() declared in an interface. The compiler rejects such code with an error"Method m() should override a method declared in a superclass"
I would find such an annotation as useful though.
The mispell is not such a problem: if the compiler doesn't find a method implementation of the correct namem(), it will signal an error requesting that the class be abstract.
But the explicit documentation would be welcome: in a class that extends a superclass, implements a couple of interfaces, and adds a few methods of its own, it is not so obvious whether a method m() actually implements a method declared in an interface.
So my questions:
- Did I miss anything, such as, an option of @Override that would make it applicable to the implementation of a method declared in an interface, or a specific-purpose @Implements annotation?
- Do you find @Override that useful, and would you find it more useful to have it applicable to such methods? Or would you find an @Implements annotation useful?
I'm planning to open an RFE about this.
[1780 byte] By [
jdupreza] at [2007-11-26 20:52:50]

# 1
Sun never (well at least rarely) breaks backward compatibility, so your suggestions would need to incorporate that sad reality. That having been said, I find @Override useless. My IDE already tells me when a method is implementing an interface or overriding an ancestor. - Saish
# 2
> I find @Override useless. My IDE already tells me
> when a method is implementing an interface or
> overriding an ancestor.
Certainly it would be useless for that purpose, and I'm sure that's why it doesn't apply to interfaces. But I don't think that's what it's for.
Your compiler tells you everything you need to know about your class's relationship to the interface. Either you've implemented (note, implement, not override) the appropriate methods or your class won't compile.
What the compiler can't tell you conventionally, but can with the @Override annotation, is that a method that you thought over-rode an inherited method has a different signature.
For example, this method silently does something unexpected when the toString() method is called on the object:
public String toStrign() {
// ...
return "something";
}
Whereas this method won't compile because the signature doesn't match anything in the super-classes:
@Override
public String toStrign() {
// ...
return "something";
}
(edit) On re-reading what both posters have said, I realise I'm probably just re-stating stuff they've said between them. But I'll leave it here anyway.
# 3
From the OP:
But the explicit documentation would be welcome: in a class that extends a superclass, implements a couple of interfaces, and adds a few methods of its own, it is not so obvious whether a method m() actually implements a method declared in an interface.
When do you need this? Normally you care that the class implements the interface (in which case the method's guaranteed to be there), or that it provides a method and the interface isn't relevant.
Under what circumstances would you need to know that a method was provided by virtue of its existence in an interface that the class implemented? Seems kind of misguided to me. Even assuming that it weren't, however, the information is already available to the compiler - there's no point in adding an annotation or extending the existing one to this purpose.
# 4
If you create a method in a class that has a superclass that resides in a different package, and later that super class adds a method, you may not notice that your method is now overriding that super class method. this helps a lot for that.
Still though a bad situation exists for inner classes where you do not know if yoru calling a method on the containing class or the super class... Further, modification of the super class can cause the class you call to change. in this case I usually qualify all methods and variables with OuterclassName.this.xxx. or super.xxx.
I wish the compiler would flag that as a potential problem. Perhaps refuse to compile if methods of the same name exist on the super class as well as the outerclass. i dont know if 5.0 will do that.
# 5
Ok those are real issues, although fairly marginal. I think they'd be better addressed by improved test suite coverage than anything that annotations can address.
# 6
Thanks for your feedback. Lots of points, I'll try to address them.
> Sun never (well at least rarely) breaks backward
> compatibility, so your suggestions would need to
> incorporate that sad reality.
Right, I hadn't thought about that. Thinking, about it though, I don't see how either proposal would affect backwards compatibility, anymore than the current @Override annotation: the ancestry of a method is checked only if the annotation is present.
> That having been said,
> I find @Override useless. My IDE already tells me
> when a method is implementing an interface or
> overriding an ancestor.
Not everyone is using IDEA :o) , anyway that's a vast debate about what should be in the language and what shuld be in the IDE.
> When do you need this? Normally you care that the class implements the
> interface (in which case the method's guaranteed to be there),
> or that it provides a method and the interface isn't relevant.
When you first write a class, sure, but when you maintain existing code, you may lack awareness of which method is declared where.
> Under what circumstances would you need to know that a method
> was provided by virtue of its existence in an interface
> that the class implemented?
Generally, you don't rewrite the javadoc for such a method, so if you are maintaining the subclass and wondering what the contract of the method is, you will have to go look at the declaration. Saish is right though in that a decent IDE will enable you to jump to the original declaration.
Indeed if the original developper did rewrite the javadoc, you may not even notice that the method may be called through a more general type, with a more general contrat.
> Seems kind of misguided to me.
Sorry, I am not a native english speaker, I had to check a dictionary to evaluate how harsh you were on me :o)
> the information is already available to the compiler
> there's no point in adding an annotation or extending the existing one to this purpose.
I've only a few month of experience with version 5 of the JDK, so I may be overrestimating the usefulness of @Override in maintenance. I viewed it as a design-documenting tool in addition to a spell-check utility. With this point of view, there's no reason to ban it for method declared in an interface.
Apparently Sun views it as a spell-check utility (OK I'm a bit overstated: it is more generally a signature-check tool as it takes arguments types into account), and with their point of view there's no point in applying it for interfaces.
Time will tell. I will wait that the code is maintained by the next team before submitting my RFE :o)
> I think they'd be better addressed by improved test suite coverage
> than anything that annotations can address.
I am a big supporter and word-spreader of unit testing, but I don't think unit tests are the correct level for things that a compiler could catch. I would never have written a unit test to check that my hashCode() method was correctly spelled. Fortunately now I don't need to, thanks to @Override...
J.
P.S.: I don't know whether it's a bad sign, but I keep mispelling @Overrdie :o)
# 7
> When you first write a class, sure, but when you
> maintain existing code, you may lack awareness of
> which method is declared where.
But the circumstances are going to be:
Provided in an interface: Won't compile if you don't honour the contract.
Provided in a superclass abstract: ditto. And @Override applies.
Provided in a superclass concrete: @Override applies.
Not provided in a superclass or interface: @Override not relevant anyway, and either honours contract or dependent classes don't compile. The exception is if you're writing a library method.
I don't see the advantage of knowing where the method is declared for any of these. The compiler's going to tell you if you get it wrong in a significant case, the exceptions being ones that this hypothetical @Override extension can't help and which a test suite can cover anyway.
> Generally, you don't rewrite the javadoc for such a
> method, so if you are maintaining the subclass and
> wondering what the contract of the method is, you
> will have to go look at the declaration.
But it will be in the Javadoc, even if you don't provide a doc comment. So this doesn't apply.
> Sorry, I am not a native english speaker, I had to
> check a dictionary to evaluate how harsh you were on
> me :o)
I'm usually fairly blunt when I'm being intentionally rude. That's me saying "you're wrong" as politely as possible. :-)
> I viewed it as a
> design-documenting tool in addition to a spell-check
> utility.
I disagree completely about the design-documenting aspect of this. As far as I'm concerned it is purely an announcement to the compiler of your intention when declaring the method: This method is intended to override something in the superclass. The compiler can then draw your attention to it if it doesn't for some reason.
Having created some cretinous but insidiously difficult to analyse bugs with typos and otherwise incorrect method signatures where I thought I was overriding a method but wasn't really, I really like this feature exactly as it's implemented. I'd get no benefit from the hypothetical announcement of implementation of interface methods because they're already mandatory and will fail politely if I screw up.
Note, it's not just typos but incorrect parameter types or correct but misordered parameter types that the existing annotation will catch.
> With this point of view, there's no reason
> to ban it for method declared in an interface.
I just don't understand what advantage you will get. What additional information do you believe it would make available to the Javadoc tool that's not already available to the Javadoc tool? Remember we already know that a method implements a given method in a given interface (or interfaces) because that type information is available (and must be or it won't compile) at compile time.
> I am a big supporter and word-spreader of unit
> testing, but I don't think unit tests are the correct
> level for things that a compiler could catch.
Agreed. What do you believe you're adding that the compiler can't (and doesn't) already catch?
D.
# 8
I agree with DCMinter. IMO, @Override is like a marker interface. They are 'somewhat documenting' but do not really add value.- Saish
# 9
I do think @Override adds value. Just not as "documentation". That may be what you were saying, but I wanted to clarify.
# 10
I've left this unattended for a few months, but it appears an RFE had already been opened: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5008260
Moreover, a comment in this very RFE report suggests that "Interestingly, JDK6 has this problem silently fixed.", but I doubt this is right (I'm currently using JDK 6 and still face errors if I specify an @Override annotation for a method that is only specified in an interface.).
# 11
> Moreover, a comment in this very RFE report suggests
> that "Interestingly, JDK6 has this problem silently
> fixed.", but I doubt this is right (I'm currently
> using JDK 6 and still face errors if I specify an
> @Override annotation for a method that is only
> specified in an interface.).
I think the errors are correct. To "override" a concrete method of superclass and to "implement a method of an interface" are two different things.
If they created an annotation, i.e. @Override, to indicate that a method "overrides" another method, then that is what it should be used for, and only that.
There are differences between a Java interface class and a Java concrete class. The interface class only declares method signatures and does not contain any implementations.
Again, @Override should only be allowed in one case, when a concrete superclass method is overriden. Introducing ambiguity by allowing an "override" annotation to be used in cases where there is no "overriding" happening is poor design, in my opinion.
That said, I rarely "override" anything and use inheritence sparingly if ever in my own code.
# 12
oops, my mistake, nothingMessage was edited by: developer_jbs