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

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

Related

Why the use of "default" keyword in java8

In Java 8 default method implementation is introduced. My question is why the need to have default keyword in the method name/signature. Why can't it be without the default keyword just like a usual method implementation?
It makes the intention clear. You can't accidentally create a default implementation for a method. Just like abstract methods require the keyword, instead of just being methods without implementation.
A safety precaution for the careless programmers.
It is worth noting that since Java 8 interfaces also support static methods. Leaving out the default keyword opens the door to ambiguity: would a method declaration in an interface that has no modifier be implicitly static (like constants), or implicitly default? As it is, everything is clear.
Note: This is speculation, but educated speculation. What #Kayaman's answer says is also likely true.
Java aims to be as backward compatible as possible. If you didn't include the default keyword then potentially invalid code, perhaps written by mistake, in a previous java version now compiles on Java 8+. This can be viewed as breaking backwards compatibility.
In Java 8, “Default Method” or (Defender methods) feature, which allows the developer to add new methods to the interfaces without breaking their existing implementation. It provides the flexibility to allow interface to define implementation which will use as the default in a situation where a concrete class fails to provide an implementation for that method.
You can refer the below URL to understand more details.
https://dzone.com/articles/interface-default-methods-java

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.

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.

How to annotate deprecation of a class in 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.

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.

Categories