How to annotate deprecation of a class in Java? - java

I am going to deprecate a class in Java.
#Deprecated
class deprecatedClass
and I have list of this deprecated class,
List<deprecatedClass> listOfDeperecatedClass
So do I need to add the #Deprecated tag for this list too?
Edit: #Deprecated should have a capital 'D'.
See: http://docs.oracle.com/javase/7/docs/api/java/lang/Deprecated.html

No, you don't need to. Adding the annotation #Deprecated to DeprecatedClass will generate a warning every time it's used.
What you should do however, is marking methods in other classes that take your deprecated class as an argument or return it, as deprecated as well. That goes for any access that other code may have to instances of your deprecated class — public fields, constants and so on. Those of course can't be used without an instance of your deprecated class, so the warning is given anyway, but in a correct deprecation annotation and comment, you should provide an explanation and point to an alternative, which is valuable information you need to give.
A method signature is like a contract and so is a class signature. You're telling other programmers what methods they can call and how they can call them. You're telling them which fields are accessible. Other programmers base their code on that. If you really need to break that contract, you first need to provide a substitute for that contract (a new method with the same functionality), and tell them and give them time to switch to that new contract (deprecate the old methods and classes).
Of course, the above assumes that you're coding to an audience. If you're the only one using your code and you just want to deprecate to clean up your code without breaking the build, just deprecate the class, fix the warnings, and remove it.

Do you have operations on the List as part of your public interface? In that case, mark all those methods as deprecated too. Otherwise you should be fine.

You only need to add the deprecation message to the declaration of anything you are deprecating. It serves as a warning that people should avoid an implementation which uses the deprecated class, such as in List<DeprecatedClass>.

Just marking as:
#Deprecated
List<deprecatedClass> listOfDeperecatedClass
Should be okay.

Something to note for people who stumble on this question like I did...
I am on OpenJDK 14 and I see capital D does not work but lower case D works! My Intellij says wrong tag #Deprecated vs. no such warning with lower case D.
Secondly, when I compile my maven project also only lower case D shows the warning below...
[WARNING] <....>.java: <....>.java uses or overrides a deprecated API.
[WARNING] <....>.java: Recompile with -Xlint:deprecation for details.

Related

Why don't classes in the JCL explicitly use `#Override` on their `toString()` methods?

The API specification page for the Object class for the method toString() states:
"It is recommended that all subclasses override this method."
Therefore I expect to see the #Override annotation in a lot of classes in the Java Class Library. I looked, and it is neither present in the class 'Class' nor the class 'String'.
These are the only two I checked, but assuming this is the case for all classes in the JCL, why don't they use the #Override annotation?
Is it for performance reasons?
Is it because the classes were written before #Override was introduced?
I was under the impression that using #Override liberally was good programming practice.
That can be understood if you understand why #Override is used. The thing is that it provides benefits for sub-class maintainers only.
The main usage is like following: library A has a class SecurityManager, which has method allowed. Bob uses A at his project, he extended SecurityManager, and overridden allowed in his code. However allowed is used only by SecurityManager's internal logic, so Bob never calls it in his code, but he relies that library will use his implementation instead of basic. Then maintainers of the library created a new major version, with some breaking changes - and renamed the method to isAllowed. Bob downloaded the new version and compiler said to him "#Override doesn't override anything - recheck your code", and Bob saw that method's name changed, and fixed that.
However java is backwards compatible, so there is no sense in expecting that toString will be removed or renamed at some point of time. That's why there is no sense in adding #Override for Object's methods.

What is a deprecated annotation target - implementation, interface or both?

Hi i wonder if i have to annotate a deprecated method at all their occurrences like, Interface, Base (Abstract Class) and all the Implementation Classes or is one annotation in the Interface sufficient?
Actually depends of how deprecated classes are used. Deprecate an interface (methods or attributes) is enough if you use good practices (instantiating the interface to use the implementation).
Anyway,
you cannot ensure / force this practice in other users
not all compilers/parsers will throw a warning or show javadoc #deprecated tag
Using the #Deprecated annotation to deprecate a class, method, or field ensures that all compilers will issue warnings when code uses that program element. In contrast, there is no guarantee that all compilers will always issue warnings based on the #deprecated Javadoc tag, though the Sun compilers currently do so. Other compilers may not issue such warnings. Thus, using the #Deprecated annotation to generate warnings is more portable that relying on the #deprecated Javadoc tag.
Resuming: if you want to deprecate a method implementation you must deprecate both, interface and implementation.
SOURCES 1 2 3

Missing #Override in Java Libraries

It is considered to be a good practice to
use #Override annotation on methods which are being overriden in
subclass.
But why is same not applied to the classes that come with Java Library. For e.g. String Class. It overrides methods of Object class but does not use #Override annotation on these methods.
Is this so to maintain backward compatibility with previous releases of Java such as 1.4 etc.
Thanks
Within an API, it does not offer much to the user (of that API). However when you implement a method, and you 'intend' do override that of a super class, it is easy to miss out on the method signature, which is supposed to match.
In this case the #Override comes to the rescue as at compile time, it will fail or give a warning when the override does not happen. Also many IDE's recognize the #Override and give you enough support to flag and correct those situations before you even compile.
So the #Override in essence declares your intention that this method overrides something. The user of the API would care less what your intent is, as long as it works.
Actually, probably the true reason is this: The Retention of the #Override annotation is set to SOURCE. Which means the #Override flag is discarded when compiled into a class file.
#Target(value=METHOD)
#Retention(value=SOURCE)
public #interface Override
That is not much more of a cosmetic annotation, it's useful when generating documentation, to give hints through your Java IDE and to explicitly state when a method is overriden.
From the runtime/standard library implementors point of view, it was not worth the effort to modify all existing classes just to add something cosmetic.
Furthermore, regarding backward compatibility of annotations in general, considering that annotations are an optional and extended attribute present in .class file (when their retention policy is either CLASS or RUNTIME and available for Class and Method as Runtime(In)VisibleAnnotations and for Parameter as Runtime(In)VisibleParameterAnnotations) previous releases of the JVM would simply ignore that attribute during the .class file parsing performed the first time that Class is needed.
But actually, that 1.4 JVM class parser will not even reach the point where those Annotation .class attribute are located inside the structure because the parsing will end abruptly when the JVM will notice that the .class version is greater than the supported one.
#override annotation is used to provide some extra information, mainly while generating documentations and also for informing the developer that the code intends to override a method from the superclass.
This is mentioned in oracle documentation.
#Override #Override annotation informs the compiler that the element
is meant to override an element declared in a superclass. Overriding
methods will be discussed in Interfaces and Inheritance.
// mark method as a superclass method // that has been
overridden #Override int overriddenMethod() { }
While it is not required to use this annotation when overriding a
method, it helps to prevent errors. If a method marked with #Override
fails to correctly override a method in one of its superclasses, the
compiler generates an error.
Refer to this discussion in SO itself.

Can I view the javadoc for an implementation rather than the interface in IntelliJ IDEA?

I am using a third party library in my Intellij IDEA project. When I have the caret on a method name I can hit Ctrl-Q to get javadoc in the 'Quick Documentation Lookup' window, however only the method signature is displayed. This is because the type of object containing the method is an Interface with no javadoc comments. The actual implementation of the object does have javadoc comments. If I cast the object to the implementation type the javadoc comments will appear.
Can I do something in IntelliJ get this to work without making any code changes?
Sorry, this won't be much help. But I am wondering:
why would anybody document the implementing classes but not the interface? The interface documents the contract, that should usually be enough, and an implementing class can of course brag how well it implements the contract or state why it breaks it, but in 90% of the cases an {#inheritDoc} tag is enough for an implementation method, while the interface should define the method semantics.
One of the reasons to do it that way is the one you are just encountering: people who develop code against interfaces (and I hope we all are) need these interfaces to be documented. If I need to look up the functionality of the implementing classes, why bother with interfaces at all?
Of course there are exceptions where implementing methods should be documented (see above), and of course the implementing classes and constructors should always be documented, but an API with undocumented interfaces is in my opinion a bad API.

When do you use Java's #Override annotation and why?

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
What are the best practices for using Java's #Override annotation and why?
It seems like it would be overkill to mark every single overridden method with the #Override annotation. Are there certain programming situations that call for using the #Override and others that should never use the #Override?
Use it every time you override a method for two benefits. Do it so that you can take advantage of the compiler checking to make sure you actually are overriding a method when you think you are. This way, if you make a common mistake of misspelling a method name or not correctly matching the parameters, you will be warned that you method does not actually override as you think it does. Secondly, it makes your code easier to understand because it is more obvious when methods are overwritten.
Additionally, in Java 1.6 you can use it to mark when a method implements an interface for the same benefits. I think it would be better to have a separate annotation (like #Implements), but it's better than nothing.
I think it is most useful as a compile-time reminder that the intention of the method is to override a parent method. As an example:
protected boolean displaySensitiveInformation() {
return false;
}
You will often see something like the above method that overrides a method in the base class. This is an important implementation detail of this class -- we don't want sensitive information to be displayed.
Suppose this method is changed in the parent class to
protected boolean displaySensitiveInformation(Context context) {
return true;
}
This change will not cause any compile time errors or warnings - but it completely changes the intended behavior of the subclass.
To answer your question: you should use the #Override annotation if the lack of a method with the same signature in a superclass is indicative of a bug.
There are many good answers here, so let me offer another way to look at it...
There is no overkill when you are coding. It doesn't cost you anything to type #override, but the savings can be immense if you misspelled a method name or got the signature slightly wrong.
Think about it this way: In the time you navigated here and typed this post, you pretty much used more time than you will spend typing #override for the rest of your life; but one error it prevents can save you hours.
Java does all it can to make sure you didn't make any mistakes at edit/compile time, this is a virtually free way to solve an entire class of mistakes that aren't preventable in any other way outside of comprehensive testing.
Could you come up with a better mechanism in Java to ensure that when the user intended to override a method, he actually did?
Another neat effect is that if you don't provide the annotation it will warn you at compile time that you accidentally overrode a parent method--something that could be significant if you didn't intend to do it.
I always use the tag. It is a simple compile-time flag to catch little mistakes that I might make.
It will catch things like tostring() instead of toString()
The little things help in large projects.
Using the #Override annotation acts as a compile-time safeguard against a common programming mistake. It will throw a compilation error if you have the annotation on a method you're not actually overriding the superclass method.
The most common case where this is useful is when you are changing a method in the base class to have a different parameter list. A method in a subclass that used to override the superclass method will no longer do so due the changed method signature. This can sometimes cause strange and unexpected behavior, especially when dealing with complex inheritance structures. The #Override annotation safeguards against this.
To take advantage from compiler checking you should always use Override annotation. But don’t forget that Java Compiler 1.5 will not allow this annotation when overriding interface methods. You just can use it to override class methods (abstract, or not).
Some IDEs, as Eclipse, even configured with Java 1.6 runtime or higher, they maintain compliance with Java 1.5 and don’t allow the use #override as described above. To avoid that behaviour you must go to: Project Properties ->Java Compiler -> Check “Enable Project Specific Settings” -> Choose “Compiler Compliance Level” = 6.0, or higher.
I like to use this annotation every time I am overriding a method independently, if the base is an interface, or class.
This helps you avoiding some typical errors, as when you are thinking that you are overriding an event handler and then you see nothing happening. Imagine you want to add an event listener to some UI component:
someUIComponent.addMouseListener(new MouseAdapter(){
public void mouseEntered() {
...do something...
}
});
The above code compiles and run, but if you move the mouse inside someUIComponent the “do something” code will note run, because actually you are not overriding the base method mouseEntered(MouseEvent ev). You just create a new parameter-less method mouseEntered(). Instead of that code, if you have used the #Override annotation you have seen a compile error and you have not been wasting time thinking why your event handler was not running.
#Override on interface implementation is inconsistent since there is no such thing as "overriding an interface" in java.
#Override on interface implementation is useless since in practise it catches no bugs that the compilation wouldn't catch anyway.
There is only one, far fetched scenario where override on implementers actually does something: If you implement an interface, and the interface REMOVES methods, you will be notified on compile time that you should remove the unused implementations. Notice that if the new version of the interface has NEW or CHANGED methods you'll obviously get a compile error anyways as you're not implementing the new stuff.
#Override on interface implementers should never have been permitted in 1.6, and with eclipse sadly choosing to auto-insert the annotations as default behavior, we get a lot of cluttered source files. When reading 1.6 code, you cannot see from the #Override annotation if a method actually overrides a method in the superclass or just implements an interface.
Using #Override when actually overriding a method in a superclass is fine.
Its best to use it for every method intended as an override, and Java 6+, every method intended as an implementation of an interface.
First, it catches misspellings like "hashcode()" instead of "hashCode()" at compile-time. It can be baffling to debug why the result of your method doesn't seem to match your code when the real cause is that your code is never invoked.
Also, if a superclass changes a method signature, overrides of the older signature can be "orphaned", left behind as confusing dead code. The #Override annotation will help you identify these orphans so that they can be modified to match the new signature.
If you find yourself overriding (non-abstract) methods very often, you probably want to take a look at your design. It is very useful when the compiler would not otherwise catch the error. For instance trying to override initValue() in ThreadLocal, which I have done.
Using #Override when implementing interface methods (1.6+ feature) seems a bit overkill for me. If you have loads of methods some of which override and some don't, that probably bad design again (and your editor will probably show which is which if you don't know).
#Override on interfaces actually are helpful, because you will get warnings if you change the interface.
Another thing it does is it makes it more obvious when reading the code that it is changing the behavior of the parent class. Than can help in debugging.
Also, in Joshua Block's book Effective Java (2nd edition), item 36 gives more details on the benefits of the annotation.
It makes absolutely no sense to use #Override when implementing an interface method. There's no advantage to using it in that case--the compiler will already catch your mistake, so it's just unnecessary clutter.
Whenever a method overrides another method, or a method implements a signature in an interface.
The #Override annotation assures you that you did in fact override something. Without the annotation you risk a misspelling or a difference in parameter types and number.
I use it every time. It's more information that I can use to quickly figure out what is going on when I revisit the code in a year and I've forgotten what I was thinking the first time.
The best practive is to always use it (or have the IDE fill them for you)
#Override usefulness is to detect changes in parent classes which has not been reported down the hierarchy.
Without it, you can change a method signature and forget to alter its overrides, with #Override, the compiler will catch it for you.
That kind of safety net is always good to have.
I use it everywhere.
On the topic of the effort for marking methods, I let Eclipse do it for me so, it's no additional effort.
I'm religious about continuous refactoring.... so, I'll use every little thing to make it go more smoothly.
Used only on method declarations.
Indicates that the annotated method
declaration overrides a declaration
in supertype.
If used consistently, it protects you from a large class of nefarious bugs.
Use #Override annotation to avoid these bugs:
(Spot the bug in the following code:)
public class Bigram {
private final char first;
private final char second;
public Bigram(char first, char second) {
this.first = first;
this.second = second;
}
public boolean equals(Bigram b) {
return b.first == first && b.second == second;
}
public int hashCode() {
return 31 * first + second;
}
public static void main(String[] args) {
Set<Bigram> s = new HashSet<Bigram>();
for (int i = 0; i < 10; i++)
for (char ch = 'a'; ch <= 'z'; ch++)
s.add(new Bigram(ch, ch));
System.out.println(s.size());
}
}
source: Effective Java
Be careful when you use Override, because you can't do reverse engineer in starUML afterwards; make the uml first.
It seems that the wisdom here is changing. Today I installed IntelliJ IDEA 9 and noticed that its "missing #Override inspection" now catches not just implemented abstract methods, but implemented interface methods as well. In my employer's code base and in my own projects, I've long had the habit to only use #Override for the former -- implemented abstract methods. However, rethinking the habit, the merit of using the annotations in both cases becomes clear. Despite being more verbose, it does protect against the fragile base class problem (not as grave as C++-related examples) where the interface method name changes, orphaning the would-be implementing method in a derived class.
Of course, this scenario is mostly hyperbole; the derived class would no longer compile, now lacking an implementation of the renamed interface method, and today one would likely use a Rename Method refactoring operation to address the entire code base en masse.
Given that IDEA's inspection is not configurable to ignore implemented interface methods, today I'll change both my habit and my team's code review criteria.
The annotation #Override is used for helping to check whether the developer what to override the correct method in the parent class or interface. When the name of super's methods changing, the compiler can notify that case, which is only for keep consistency with the super and the subclass.
BTW, if we didn't announce the annotation #Override in the subclass, but we do override some methods of the super, then the function can work as that one with the #Override. But this method can not notify the developer when the super's method was changed. Because it did not know the developer's purpose -- override super's method or define a new method?
So when we want to override that method to make use of the Polymorphism, we have better to add #Override above the method.
I use it as much as can to identify when a method is being overriden. If you look at the Scala programming language, they also have an override keyword. I find it useful.
It does allow you (well, the compiler) to catch when you've used the wrong spelling on a method name you are overriding.
Override annotation is used to take advantage of the compiler, for checking whether you actually are overriding a method from parent class. It is used to notify if you make any mistake like mistake of misspelling a method name, mistake of not correctly matching the parameters
i think it's best to code the #override whenever allowed. it helps for coding. however, to be noted, for ecipse Helios, either sdk 5 or 6, the #override annotation for implemented interface methods is allowed. as for Galileo, either 5 or 6, #override annotation is not allowed.
Annotations do provide meta data about the code to the Compiler and the annotation #Override is used in case of inheritance when we are overriding any method of base class. It just tells the compiler that you are overriding method. It can avoide some kinds common mistakes we can do like not following the proper signature of the method or mispelling in name of the method etc. So its a good practice to use #Override annotation.
For me the #Override ensures me I have the signature of the method correct. If I put in the annotation and the method is not correctly spelled, then the compiler complains letting me know something is wrong.
Simple–when you want to override a method present in your superclass, use #Override annotation to make a correct override. The compiler will warn you if you don't override it correctly.

Categories