This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 118928 - [68cat] @Override annotation warnings, hints and auto-generation
Summary: [68cat] @Override annotation warnings, hints and auto-generation
Status: REOPENED
Alias: None
Product: java
Classification: Unclassified
Component: Project (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker with 5 votes (vote)
Assignee: Tomas Zezula
URL:
Keywords:
: 124205 134249 162258 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-10-15 18:57 UTC by Chris Webster
Modified: 2016-07-18 19:59 UTC (History)
8 users (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Webster 2007-10-15 18:57:34 UTC
this causes multiple warnings in the code. The must be repaired one by one. 

The steps I did:

* Create a class which implements an interface (and extends an abstract class)
* Use Alt-Ins to select the methods.
* The generation proceeds as expected; however, the override annotation is not generated which triggers multiple
warnings because of the missing override.
Comment 1 Jan Lahoda 2007-10-16 08:59:22 UTC
What build are you using? What is your source level? Seems to work fine for me.
Comment 2 _ gtzabari 2008-01-08 06:36:11 UTC
*** Issue 124205 has been marked as a duplicate of this issue. ***
Comment 3 _ gtzabari 2008-01-08 06:38:12 UTC
dev build 200801061200
Project with JDK6-level source compatibility

Invoking code-complete on an abstract class (i.e. AbstractList) adds the @Override annotation per method. Attempting the
same thing on an interface (i.e. Set) results in methods without the @Override annotation.

This seems like a pretty clear-cut bug. If the source-level compatibility is set to JDK6 and above interfaces should get
@Override as well.
Comment 4 matthies 2008-01-08 07:06:50 UTC
Since it has been marked as a duplicate of this issue, I'm adding my comments from issue 124205 here, as it actually 
represents a somewhat broader view of the general issue:

On the one hand, the "Implement all abstract methods" hint generates methods with an @Override annotation.
On the other hand, for an implementation of an abstract method no "Add @Override annotation" hint is shown, and the I-
in-green-circle editor annotation is shown rather than the O-in-green-circle one.
I beliebe this is inconsistent.

Java allows @Override annotations on methods implementing abstract methods, but not on methods implementing interface 
methods. This is somewhat controversial, and I suppose that's the reason why the "I" editor annotation and no "Add 
@Override annotation" hint is shown for methods implementing abstract methods. (This must have changed quite late in 
the 6.0 dev builds, I think.) But then the "Implement all abstract methods" hint shouldn't generate @Override 
annotations either. Pick one policy, and stick with it throughout the editor.

Since it's a contentious issue whether @Override annotations belong on methods that implement abstract methods, you 
might want to make the policy configurable and add a corresponding flag in the Options.
Comment 5 Jan Lahoda 2008-02-11 16:53:32 UTC
Two separate problems, IMO:
I. Adding @Override annotations
I tried to make sure that the Java editor produces the @Override annotations on all methods it can. The change is in
Mercurial changeset id: db947d77f4ca (will be public on my next push to shared repository). The change is mostly adding
tests, the semantics remains as it was.

The situation is as follows:
-the behavior and meaning of java.lang.Override changed between JDK 5 and JDK 6 - see:
http://blogs.sun.com/ahe/entry/override
the Java editor produces @Override annotations based on the current source level - when the source level == "1.6",
@Override annotation is generated on all methods (including methods from interfaces) (should be safe, JDK 5 compiler
will not accept source level == "1.6"). For source level == "1.5", it adds @Override annotation only at the methods
coming from a superclass. The "Add @Override annotation" hints should behave in the same way.

To my current knowledge, the Java editor does the best it can: the @Override annotations are generated on all places
where they could be without causing compilation errors. If you have a case they are not, please open a new bug with very
exact steps to reproduce.

The problem with the "Source/Binary Format" combo in the J2SE Project customizer is that this combo actually does not
set the source level to "1.6", it only changes the "target level" to "1.6", but there is no way for the Java editor to
react on this change. I am passing this to the J2SE Project to resolve this.


II. "I" and "O" annotations
I think this is quite independent on the @Override annotation - method override is defined in JLS 8.4.8.1, and method
that overrides an abstract method is said to implement it. The "I" appears for methods that implement other methods, "O"
for methods that do not implement at least one method, but override at least one method. I think that this behavior is
consistent.
Comment 6 matthies 2008-02-12 13:09:20 UTC
Basing the editor's behavior on the source level (javac.source) is not really correct, I believe. This is because 
javac's behavior does not actually depend on the specified source level: javac 1.6 uses the 1.6 semantics even with -
source 1.5. So wouldn't it be more appropriate to look at the javac (or JDK) version?
Comment 7 Jan Lahoda 2008-02-12 14:00:26 UTC
I am afraid that I do not see any "fully correct" solution. The current is the best I know. Basing the decision on the
instance of the javac used to build the project will not work - the project with source level 1.5 can be switched from
JDK6 to JDK5 (without any warning), and the already generated @Override annotations would cause build failures (the same
holds for sharing the project through a VCS).
Comment 8 _ gtzabari 2008-02-12 14:35:22 UTC
I don't see the same ambiguity that you two do. The way I see it it's very simple:

1) Switching the source level from 1.6 to 1.5 won't change existing @Override and compilation errors may occur. This is
okay and I doubt any users would expect otherwise. Put it another way, if they hand-coded some 1.6-specific code they
won't expect Netbeans to magically change their code.

2) I believe it is appropriate to use the project source level instead of javac level because what we are essentially
saying is that "This project can be compiled under JDK XXX". It doesn't matter that on the current machine your 1.6
compiler will accept @Override that 1.5 won't. What matters is that Netbeans is saying that any code that *it* generates
will be able to compile under JDK 1.5 and to the best of its ability it will try to guarantee that any code *you* wrote
is also 1.5-compliant (but the latter doesn't have to be 100%).
Comment 9 Jan Lahoda 2008-02-12 14:46:34 UTC
gtzabari: thats what I was trying to say, I guess.
Comment 10 Tomas Zezula 2008-02-12 18:02:56 UTC
I've changed the behavior of project customizers, the Java 6 source/binary format sets both the java.csource and the
javac.target to 1.6.
Commit: 3c1577e4ccfa
Comment 11 matthies 2008-03-31 18:16:29 UTC
jlahoda, you wrote: "I tried to make sure that the Java editor produces the @Override annotations on all methods it 
can." I would strongly prefer that @Override annotations be only produced when not having an annotation would otherwise 
result in a warning. Doing this would not be in conflict with what the original reporter wanted. Reopening for 
reconsideration.
Comment 12 _ gtzabari 2008-03-31 19:21:53 UTC
matthies,

Under which conditions does Netbeans apply @Override which would not otherwise produce a warning?
Comment 13 matthies 2008-03-31 20:13:11 UTC
gtzabari: When generating implementations of abstract methods. (E.g. perform "Implement all abstract methods" on "class 
Test extends AbstractList { }".) Maybe there are other cases, not sure at the moment.

It seems to me that the following three should always coincide (in the "if-and-only-if" sense):
- Warning shown when no @Override annotation present.
- Green "(O)" gutter annotation shown (as opposed to "(I)" or no annotation).
- @Override annotation added when auto-generating method.

Couldn't all three delegate to the same logic internally?
Comment 14 Jan Lahoda 2008-03-31 21:30:48 UTC
I still think that the "green O/I" means something different than the @Override annotation - the "green O" means "you
are overriding an existing body", "green I" means "you are implementing an abstract method" (if both is true, "green O"
should win). One can use the @Override annotation on a method that implements abstract method from the superclass. As of
JDK6, one can annotate with @Override even method that implements a method from interface.

I will extended the Add @Override annotation hint to cover the above scenario correctly.
Comment 15 matthies 2008-03-31 23:44:59 UTC
jlahoda: Are you saying that "green I" will produce a warning/hint too?
Because I'd absolutely, positively hate that. ;)

FWIW, here's some rationale (which may or may not convince):

1) There are three cases were I add @Override:

   a) I'm overriding an existing method body either with a new method
      body, or with an abstract declaration (basically "un-implementing"
      the method).

   b) I'm overriding an abstract or interface method declaration with
      another abstract or interface method declaration that has a
      different signature (because of type variable instantiation and/or
      because of return type specialization).
      Here the @Override is helpful to check that the new signature
      actually matches the different signature from the supertype.
      IMO enabling this for interfaces is the real improvement in JDK 6.

   c) I'm declaring a method of java.lang.Object in an interface, usually
      to  document additional requirements for implementations of the
      interface (cf. java.util.Collections.equals() for example).

   With the exception of b), this is exactly "green O".
   Adding @Override in other than these cases just increases the visual
   clutter, as far as I'm concerned.

2) There's a certain category of nested classes (that I happen to code
   quite frequently) that just consists of a small number of "green I"
   method implementations with one-line method bodies. For such nested
   classes, adding @Override annotations would significantly increase
   the line count (or line length when placed on the same line as the
   method signature - but that doesn't play well with automatic formatting
   anyway), making them much less succinct, reducing readability.
   
3) In the coding style I'm used to, polymorphic methods are commonplace,
   and use of interfaces is quite pervasive. As a result, the great
   majority of method implementations is of the "green O/I" kind, but
   only a small fraction of those is of the "green O" kind. Adding
   @Override to all "green O/I" methods would make @Override rather
   meaningless, since the great majority of method implementations
   would end up having it. Adding @Override only in the cases outlined
   in 1), on the other hand, highlights the method declarations that
   require higher-than-usual attention.

4) Earlier NB versions with JDK 5 added @Override warnings on methods
   implementing abstract methods from abstract classes, and (even worse)
   on abstract methods that just repeat an abstract or interface method
   in a super type. I found that to be highly annoying, and was much
   relieved when NB later on limited warnings to the "green O" case.
   Adding warnings for "green I" cases would create significantly more
   warnings than this earlier version already created!
Comment 16 _ gtzabari 2008-04-01 01:33:12 UTC
matthies,

I'm afraid I disagree with you. @Override is supposed to be used anytime you override a method or implement an interface
method to avoid the following type of user-error:

1) MouseAdapter implements all interface methods using an empty body
2) User comes along and extends MouseAdapter but makes a typo in his declaration
3) Instead of the user method getting invoked, the no-op MouseAdapter method gets invoked instead

This was a very common user error, especially for users defining anonymous classes which extends MouseAdapter. @Override
ensures that users get a compile-time error if they think they are overriding a method but they are not. You seem to be
misunderstanding what @Override is meant for. It isn't there for the user's sake but rather for the compiler's. It's
there to communicate a compile-time requirement.
Comment 17 matthies 2008-04-01 12:54:33 UTC
gtzabari: I don't think we disagree here. I'm all for having warnings on methods that actually override an existing 
method implementation, and hence for automatic adding of @Override in that situation. The warning in that case 
basically means "Do you really intend to override/disable the inherited implementation?". The @Override annotation then 
expresses that intent "Yes, I'm intentionally overriding/disabling the inherited implementation", and the compiler 
verifies that this expressed intent matches the reality. This corresponds to your MouseAdapter example, where the 
existing no-op implementations are being overridden (or at least are intended to be overriden - as you say users can 
get it wrong).

What I'm against, on the other hand, is adding warnings to mere implementations ("green I"), that is where no existing 
method implementation is being overridden. In other words where the method in the super type is either declared 
abstract or is a not-yet-implemented interface method. Here the warning would effectively say "Are you sure you want to 
implement this method?", which appears pretty silly to me. A typo in that situation wouldn't get unnoticed either, 
because this would cause a compile error that the method is unimplemented (in the first non-abstract class).

In addition, I'd be in favor of adding warnings when specializing return types, like in:

    interface Foo { List<? extends Foo> children(); ... }
    interface Bar extends Foo { ArrayList<? extends Foo> children(); ... } // probably not intended
    interface Baz extends Foo { List<? extends Baz> children(); ... } // probably makes sense

Such warnings would mean "Did you really mean to specialize the return type of that method?" (childrens of Bar might 
actually still be just Foos). And an @Override annotation would mean "Yes, I'm doing this intentionally."


But, I don't think that warnings are appropriate for the following cases (and hence @Override annotations shouldn't be 
generated there either) (some required 'public' modifiers omitted):

A)
    interface Foo { int f(); ... }

    class FooImpl implements Foo { int f() { ... } ... }  // please no warning here

B)
    abstract class Foo { abstract int f(); ... }

    class FooImpl extends Foo { int f() { ... } ... }  // please no warning here

C)

    class Foo { int f() { ... } ... }

    abstract class Bar extends Foo { abstract int f(); ... }  // do warn here

    class BarImpl extends Bar { int f() { ... } ... }  // please no warning here

D)
    interface Foo<T> { T f(); ... }

    interface Bar extends Foo<Integer> { Integer f(); ... }  // please no warning here, but:

    interface Baz extends Foo<Number> { Integer f(); ... }  // ok to warn here

    interface Qux<T extends Number> extends Foo<T> { T f(); ... }  // please no warning here either

E)
    interface Foo<T> { T f(); ... }

    abstract class Bar implements Foo<Integer> { abstract Integer f(); ... }  // please no warning here, but:

    abstract class Baz implements Foo<Number> { abstract Integer f(); ... }  // ok to warn here

    abstract class Qux<T extends Number> implements Foo<T> { abstract T f(); ... }  // please no warning here either

F)
    abstract class Foo<T> { abstract T f(); ... }

    abstract class Bar extends Foo<Integer> { abstract Integer f(); ... }  // please no warning here, but:

    abstract class Baz extends Foo<Number> { abstract Integer f(); ... }  // ok to warn here

    abstract class Qux<T extends Number> extends Foo<T> { abstract T f(); ... }  // please no warning here either


I hope that's comprehensive enough. ;)
Comment 18 _ gtzabari 2008-04-01 13:45:54 UTC
The only counter-example I can think of (but maybe there are others) is if a concrete class implements an interface or
abstract method which subsequently gets removed in a later revision. If the method has an @Override annotation you would
get a compilation error which would notify you the method should be removed, which seems like a good thing. The only
catch is that this use-case is rare in practice. Can anyone think of another?
Comment 19 matthies 2008-04-01 14:03:23 UTC
gtzabari: With regard to your counter-example: The method shouldn't necessarily be removed. It should only be removed 
if it was only accessed through the interface/abstract super class. But there may also be direct clients of the 
concrete class. Also, not removing the method doesn't break anything. In the worst case, it's just dead code. I 
wouldn't appreciate a warning on something just for the remote possibility that it might eventually become dead 
code ;). Even actual dead code (unused private methods) isn't considered worth a warning, just a different highlighting.
Comment 20 Jiri Prox 2008-04-11 00:52:37 UTC
moving opened issues from TM <= 6.1 to TM=Dev
Comment 21 Jiri Prox 2008-04-30 13:32:47 UTC
*** Issue 134249 has been marked as a duplicate of this issue. ***
Comment 22 matthies 2008-07-16 17:03:40 UTC
I'd like to bump this issue. Can we get a consensus on this and get it fixed for 6.5?
The consensus I hope for is:

- Only methods with "green O" (as opposed to "green I") without an @Override annotation should generate a warning. If 
this consensus cannot be reached, then the behavior for "green I" should be configurable.

- In the absence of a warning, methods with "green I" without an @Override annotation may still generate a hint for 
adding an @Override annotation.

- Auto-generation of @Override annotations (e.g. when auto-generating missing implementations of abstract methods) 
should only occur for methods where a missing @Override annotation would otherwise cause a warning.

See my comment from Apr 1 11:54:33 for some rationale.
Comment 23 Chris Webster 2008-07-16 18:23:18 UTC
For warnings, would be be possible to automatically add the @Override annotation for all methods instead of requiring
you to go one by one. 
Comment 24 matthies 2008-07-16 19:19:39 UTC
@cwebster: Not considering each method individually would pretty much defeat the purpose of the warnings, wouldn't it?

Incidentally this proves the point that there should be no warnings on mere implementations ("green I"), because there 
is really nothing to warn about there. A warning is appropriate when you disable an existing implementation by 
overriding without documenting that intent with an @Override annotation.
Comment 25 Jan Becicka 2008-07-22 15:38:17 UTC
I'm lost. What are we expected to do?
Comment 26 Chris Webster 2008-07-22 16:34:23 UTC
I would vote for inserting @Override whenever Alt-Ins is used to implement or override a method and is allowed by the
compiler. 
Comment 27 matthies 2008-07-22 17:26:49 UTC
@jbecicka: I'll try to recap:

1) There are cases (the "green I" methods) where missing @Override annotations cause warnings to be generated where, 
according to what I've written previously, no warnings should be generated.

2) There are cases where automatic code generation generates @Override annotations although the absence of those 
annotations would not cause warnings.

3) The behavior of 1 depends on the javac.source setting, but the project properties dialog doesn't allow this to be 
chosen independently from the javac.target setting. This is sometimes a problem.

With regard to 1, here are some cases where NetBeans with javac.source=1.6 generates warnings where IMHO it shouldn't:

    interface Foo { void f(); }
    class FooImpl implements Foo { public void f() { } }

    abstract class Foo2 { abstract void f(); }
    class Foo2Impl extends Foo2 { public void f() { } }

    interface Foo3<T> { T f(); }
    interface Bar3 extends Foo3<Integer> { Integer f(); }

See my comments from April 1 for a richer set of test cases.

With regard to 2, for example "Implement all abstract methods" generates @Override annotations pretty much wherever an 
@Override annotation is legal for the javac.source setting, disregarding whether not doing so would cause a warning or 
not. In particular it generates an @Override annotation in the follwing case although with javac.source=1.5 the absence 
of an @OVerride annotation would NOT cause a warning:

    abstract class Foo2 { abstract void f(); }
    class Foo2Impl extends Foo2 { }


To answer your actual question, here is what I would expect, or at least very much hope for, to be done:

1) Restrict warnings caused by the absence of an @Override annotation to methods with a "green O". Don't warn on "green 
I" methods.

2) Auto-generate @Override annotations only in thoses cases where their absence would cause a warning.

3) If the resulting behavior still depends on the javac.source setting (I'm not 100% sure whether it would), make that 
a separate setting from javac.target in the project properties dialog.

Optionally / nice to have:

4) Still provide an "Add @Override Annotation" hint on "green I" methods. Make this an option under Options -> Java 
Code -> Hints. To be totally clear, by "hint" I mean a non-warning light bulb that only shows up when placing the caret 
on the respective method declaration.

5) For those who really really want warnings for "green I" methods, provide an option for that. (Note that this implies 
different behavior for javac.source=1.5 vs. javac.source=1.6.)

6) There are certain "green I" cases that can arguably be considered to constitute overriding in a certain sense. The 
first case is narrowing a return type via covariant return types, e.g.:

    interface Foo4 { Number f(); }
    interface Bar4 extends Foo4 { Integer f(); }

The second case is instatiation of type parameters, e.g.:

    interface Foo5<T> { T f(); }
    interface Bar5 extends Foo5<Integer> { Integer f(); } 

And lastly there is the sort-of combination of both of the above by narrowing type parameters, e.g.:

    interface Foo6<T> { T f(); }
    interface Bar6<T extends Number> extends Foo6<T> { T f(); }

Options (separate ones) could be provided to cause warnings for those cases as well.

If any of those optional warnings (5, 6) are provided, make sure that auto-generation (2) pays attention to those 
options. Ideally, generation of warnings and auto-generation of @Override annotations should simply invoke the same 
underlying program logic to decide whether to warn/auto-generate.
Comment 28 _ gtzabari 2008-07-22 20:15:10 UTC
matthies,

Does the warning on missing @Override come purely from Netbeans or does javac/JLS play any part of this? If the latter
hints/warns that implemented methods should have an @Override annotation then I would say you should also file a RFE
against javac.
Comment 29 matthies 2008-07-22 21:38:51 UTC
gtzabari:

The warnings are purely a NetBeans feature. The javac documentation is completely silent about the possibility of such 
warnings, and javac with all warnings turned on (-Xlint) doesn't generate any warnings for absent @Override annotations.

The JLS only defines where @Override annotations are legal. That doesn't mean that it makes sense to put @Override 
annotations everywhere the JSL allows it, or that not putting an @Override annotation in a place where the JSL allows 
one necessarily warrants a warning.
Comment 30 _ gtzabari 2008-07-22 22:27:12 UTC
Okay so I agree with your assessment.
Comment 31 matthies 2008-07-22 22:41:30 UTC
Slight correction: I wrote that the JLS defines where @Override annotations are legal. Well actually, the JLS doesn't 
do that. The relevant section [JLS:9.6.1.4] is pretty vague, and the "Discussion" part even says something which isn't 
true anymore for javac 1.6 (regardless of source level!):

"Note that if a method overrides a method from a superinterface but not from a superclass, using @Override will cause a 
compile-time error."

Obviously this has changed with JDK6. As a side note, what is interesting is what follows:

"The rationale for this is that a concrete class that implements an interface will necessarily override all the 
interface's methods irrespective of the @Override annotation, and so it would be confusing to have the semantics of 
this annotation interact with the rules for implementing interfaces."

This comment is completely right, and it's even more confusing to get warnings about a missing @Override annotation in 
those "will necessarily override (really: implement) anyway" cases. End side note.

Where @Override annotations are legal is actually specified by the JDK Javadocs [JDK6:Override]:

"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."

This specification matches the actual javac behavior when one applies the JLS' definition of "override" in 
[JLS:8.4.8.1] (which, counter-intuitively, encompasses "implements").

References:
[JLS:9.6.1.4] http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html#9.6.1.4
[JDK6:Override] http://java.sun.com/javase/6/docs/api/java/lang/Override.html
[JLS:8.4.8.1] http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.1
Comment 32 _ gtzabari 2008-10-30 06:28:48 UTC
Just double checking: will this make it into Netbeans 6.5 as the Target Milestone states? I hope so... At the very least
please stop warning about missing @Override for methods that implement an interface as matthies mentioned.
Comment 33 matthies 2008-10-30 17:12:44 UTC
I would hope so too, but currently it doesn't look like it... :(
Comment 34 matthies 2009-02-20 22:52:54 UTC
Is there any prospect on this being fixed in the near future, or will this slip by 6.7 as it did 6.1 and 6.5?
I'm asking because this issue is still a continuous annoyance.
Comment 35 matthies 2009-04-08 13:29:38 UTC
Changing summary text to reflect the more general topic this issue has grown into.
Comment 36 Jiri Prox 2009-04-09 11:18:28 UTC
*** Issue 162258 has been marked as a duplicate of this issue. ***
Comment 37 Sergey Petrov 2009-04-13 12:01:41 UTC
If I got this issue right(with a lot of comments).
Still reproducible with 6.7m3, no overrride annotaion is added to implemented  methods and no override hindt.
For abstract methods @Override is added during generation but no "override hint" if @override is deleted.
For other methods (not abstract) both hint and @Override generation is present.
Comment 38 matthies 2009-04-15 21:08:11 UTC
sergeyp: To recapitulate, the goals are:

1) Warnings about a missing @Override annotation should appear only on methods that have a "green O" and where the 
currenct javac.source setting allows an @Override annotation.

2) Auto-generation of @Override annotations should only occur on methods where a missing @Override annotation would 
otherwise cause a warning.

With regard to goal 1, the editor currently also shows warnings for "green I" methods, at least with javac.source=1.6, 
which it shouldn't. See previous comments for examples.

With regard to goal 2, for example "Implement all abstract methods" currently generates @Override annotations pretty 
much wherever an @Override annotation is legal for the javac.source setting, disregarding whether not doing so would 
cause a warning or not. This is currently the case for javac.source=1.5, and, assuming goal 1 being met, also for 
javac.source=1.6. Other refactorings or functions that generate method declarations might also be affected. Again, see 
previous comments for examples.

So, what needs to be done? The following:

i) Restrict warnings caused by the absence of an @Override annotation to methods with a "green O". Don't warn on "green 
I" methods.

ii) Restrict auto-generation of @Override annotations to those cases where their absence would cause a warning.

Since you mentioned abstract methods, please note that the desired behavior, i.e. "green I" vs. "green O" does not 
depend on the abstractness of the overriding method, but only on the abstractness of the overridden method. In 
particular, an abstract method can override a non-abstract method, in which case the overriding method is "green O", 
although it is abstract.
Comment 39 sflemming 2009-04-24 11:06:30 UTC
I just found a strange @Override behaviour that looks like a bug to me.

Steps to reproduce:

* Created a java class ( in my case with idlj ) that overrides some methods.
* An editor hint is shown that I should add the @Override annotation and I do it.
* Now the class does not compile anymore and throws "method does not override a method from its superclass".

The problem is that my Default JVM and so the initial JVM for the project is 1.5. When I switch the Project JVM to 1.6, compilation works.
But the hint should not appear when @Override is not supported


Comment 40 matthies 2009-10-28 18:54:54 UTC
Still no progress it seems.
Comment 41 _ gtzabari 2010-04-13 18:33:51 UTC
On second thought, I now see the point of @Override on methods that implement interface methods. If a user implements a method that gets removed from the interface in the future, the @Override annotation will notify him of unused code.

Granted, this use-case is extremely rare (methods are rarely removed from interfaces) but I see the point.

I'm retracting my original vote. I'm not against or for this feature request. If there is sufficient demand, consider making this behavior configurable so end-users can decide for themselves.
Comment 42 Jesse Glick 2010-04-13 19:27:51 UTC
(In reply to comment #29)
> javac with all warnings turned on (-Xlint) doesn't generate any
> warnings for absent @Override annotations.

But it probably should, and in the future it might.


FWIW, in C# the override keyword is mandatory, and this applies even to implementations of abstract methods:

  http://msdn.microsoft.com/en-us/library/ebca9ah3.aspx

The designers of C# wished to avoid the kinds of problems that occur in Java programs due to the lack of syntactic notation for a method which intentionally matches the signature of a method in a supertype. @Override is an attempt to retroactively move Java in the same direction.
Comment 43 matthies 2010-04-13 19:49:32 UTC
The override keyword is not mandatory per se in C#/.NET. If you leave it out, and there exists a matching inherited method, then the current method behaves like it was defined with the new keyword. In other words, there will be two different methods with the same name and matching signature. So in C#, "new" is the default. This is why C# generates a warning, because the current method will not override the super-class method, unlike the programmer might assume. In Java, on the other hand, such a method will always override the super-class method, whether there is an @Override annotation or not.
Comment 44 matthies 2010-04-13 19:51:39 UTC
Just a few observations with regard to gtzabari's previous comment:

- The interface method being removed doesn't necessarily mean that the code is
unused. There can be existing client code that calls the method directly, not
through the interface.

- Unused methods occur all the time, whether they implement an interface method
or not. Unused methods that don't implement an interface method (and never did)
probably occur a lot more frequently, and there's no annotation that would
notify about them.

- A notification about unused code is certainly nice, but it shouldn't cause a
compiler error (as the @Override annotation is required to do).

I still think that @Override annotations do not make much sense on methods that
do not override a super-class implementation.
Comment 45 matthies 2010-04-13 20:13:53 UTC
Maybe it's worth repeating my main point in this whole argument: I _do_ like having a warning when a method that is overriding a super-class implementation is missing an @Override annotation, so that I don't accidentally override (= disable) an existing implementation where I thought I was just implementing an abstract method. My understanding is that this was also the original intent of the @Override annotation. However, when there is a warning not only in the overriding case, but also in the implementing case, then quite obviously the annotation won't able to serve this purpose any more. It won't be warning against accidental overrides any more; in particular if the IDE "helpfully" fills in @Override annotations in either case.
Comment 46 _ gtzabari 2010-04-13 23:50:36 UTC
My interpretation of @Override is "the method I am annotating only exists for the sole purpose of overriding/implementing the super method. If it no longer does this, please issue a compiler error as I need to revisit the existence of this method".

matthies, can you think of a counter-example when you wouldn't want to revisit an overriding/implementing method when its corresponding super method was missing?

<rant>
On the topic of warnings vs errors, I've had a long history of negative experiences with the C++ warning system. Many of the warnings were false-positives and too many developers happily ignored them. One of the things I loved about Java was that you either got an error or nothing at all. I am not too fond of the warning system added in Java5. Most of the time it warns me about problems that aren't my fault (many Generics design problems have no workarounds except to suppress them).
</rant>
Comment 47 matthies 2010-04-14 13:39:19 UTC
@gtzabari: Our debate is only about the implementing case. No argument about the overriding case. So, about removing abstract methods: This should happen rarely, as removing the method breaks compatibility for clients of the interface (or abstract class). Therefore, in general this can only be done for interfaces that are private to a module or project. In such cases, I usually run "Find Usages" (including "Find Overriding Method") within the project before I actually remove the method, so I can revisit the implementations and (more importantly) the call sites.

But the real point is that orphaned implementations are not critical to the correctness of a progran. They might constitute dead code, but their existence doesn't cause bugs in the program.

Accidentally overriding a super-class implementation, on the other hand, is very likely to cause bugs. And as I wrote previously, mandating @Override annotations on both overrides and mere implementations breaks the annotation's ability to warn against such cases.
Comment 48 _ gtzabari 2010-04-14 15:21:04 UTC
matthies,

You make a good point, as always :) I'm in favor of allowing users to configure @Override for abstract classes separately from @Override for interfaces.
Comment 49 markiewb 2012-12-17 18:52:50 UTC
Set target-milestone of open issue to TBD (was < 7.3, f.e. 6.8), so the issue doesn't get lost.
Comment 50 markiewb 2012-12-17 19:00:01 UTC
Set target-milestone of open issue to TBD (was < 7.3, f.e. 6.8), so the issue
doesn't get lost. This time the target milestone is really set.
Comment 51 Martin Balin 2016-07-07 07:17:42 UTC
This old bug may not be relevant anymore. If you can still reproduce it in 8.2 development builds please reopen this issue.

Thanks for your cooperation,
NetBeans IDE 8.2 Release Boss
Comment 52 matthies 2016-07-18 19:59:18 UTC
Still relevant in current dev build.