There are at the moment, two ways to mark code as depreacted in java.
Via JavaDoc
/**
* #deprecated
*/
Or as an annotation:
#Deprecated
This is my problem - I find it a bit too much to declare both, when marking a method as deprecated when using Eclipse. I really just want to use one of them.
However does using the annotation give the compiler actual useful additional information?
But only using the annotation, I cannot state why the method is deprecated - I can only do that with JavaDoc, and deprecating a method without specying why is bad.
So, can I only use one of them? Or should I really just learn to specify both?
You should use both. The Annotation allows the compiler to display a warning whenever a deprecated method is used, and the javadoc explains why. Both are important.
As per Oracle's Java Annotations tutorial:
When an element is deprecated, it should also be documented using the Javadoc #deprecated tag...
From the horse's mouth:
NOTE: The Java Language Specification
requires compilers to issue warnings
when classes, methods, or fields
marked with the #Deprecated annotation
are used. Compilers are not required
by the Java Language Specification to
issue warnings when classes, methods,
or fields marked with the #deprecated
Javadoc tag are accessed, although the
Sun compilers currently do so.
So basically, if you want a guarantee that there will be compiler warnings, you need to use the annotation. And because of some API designer's breathtaking incompetence, you need to specify the javadoc tag as well to give an explanation.
Personally, I'd say the annotation is useless and should be omitted until it's fixed, since any good compiler or IDE will display warnings with the javadoc tag as well.
You should write both.
The #Deprecated Anotation is for the Compiler and the #deprecated JavaDoc tag is for the Person who wants to know why this is deprecated.
An example can look like this:
/**
* #deprecated We dont need this Method because ...
*/
#Deprecated
public void doStuff(){..}
You should specify both.
The annotation lets the compiler know about it and trigger warnings when the method is used.
The JavaDoc attribute lets developers know about before they start using it.
These are two very different things!
This can be easily dealt with a good IDE.
Eclipse Neon, for eg. automatically adds #Deprecated annotation, when I create a javadoc #deprecated on a method or field.
So I simply write the javadoc with the appropriate explanation and let the IDE take care of adding the #Deprecated annotation, the minute I save the file.
Related
This is my first question on here and I'm pretty new to Java, so please pardon me if this is kind of a silly question.
I am working on "documenting" the expected behavior of my application from within using JavaDocs and annotations, but I'm just curious if it's appropriate or good practice to use #NotNull on a method that SHOULDN'T ever return null, but may due to future developer error.
Thanks.
This really depends on what tooling you're using. The #NotNull annotation doesn't actually do anything. Actually, there are several different #NotNull annotations provided by different libraries. None of them do anything on their own, other than signalling the programmer's intent.
To make the annotation do anything, you need to combine it with a tool that will process the annotation (either at compile time or at run time) and apply some validation to your code or your data. For example:
IntelliJ IDEA contains tools which will check that your code abides by the nullability annotations you've included.
Bean validation can be used at runtime to check, for example, that user input doesn't violate the nullability constraints.
Even without the tooling, I would say that yes, these annotations can be useful to signal intent. You can always remove the annotation if it becomes untrue.
It sounds like it would be a good idea in your case for all contributors to the codebase to use a tool, like IntelliJ IDEA, that will check for compliance with these annotations at compile time. That will help you to avoid the type of developer error that you describe.
As far as I'm aware, there is not enforced standard globally to use these types of annotations. It makes sense to use them when writing a public API, but this is project specific.
In any case, feel free to do so in your project if it would help with code clarity and readability.
It's not an anti-pattern to have javadocs with annotations.
Also, if you are considering of warning the user of your method that it shouldn't return a null, but there is a chance of that happening (since you cannot enforce it), you might want to look into the Optional class.
yes it is good practice to use #NotNull. The #NotNull Annotation is, actually, an explicit contract declaring the following:
A method should not return null.
A variable (like fields, local variables, and parameters)cannot hold a null value.
So to keep it simple, it is a good practice.
I'm having difficulties figuring out the correct way to fix the deprecation warnings on SerializationFeature.WRITE_EMPTY_JSON_ARRAYS.
Javadocs state that
Since 2.8 there are better mechanism for specifying filtering;
specifically using com.fasterxml.jackson.annotation.JsonFormat or
configuration overrides.
but I would assume that
ObjectMapper.configure(SerializationFeature.WRITE_EMPTY_JSON_ARRAYS, false);
is a configuration override, although the line above triggers a deprecation warning.
What are other alternatives that do not pollute model classes with yet another annotation? I want to configure the behaviour globally.
At the class level, you can use the #JsonInclude like:
#JsonInclude( JsonInclude.Include.NON_EMPTY )
public class MyClass ...
Also, at the mapper level you can do something like:
mapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
The Javadoc is just plain wrong.
"using com.fasterxml.jackson.annotation.JsonFormat": There are plenty of cases where annotations are patently NOT better, most notably when you can't annotate the POJOS because you don't own them, or when you need to override the annototations to get a different behavior than you usually want.
"configuration overrides": That would be great, but to my knowledge there are no other overrides that will take precedence over annotations.
From the user perspective, the only thing bad about the deprecated option is that it is deprecated, and thus might not be supported in the future. That is of course a real concern - you might one day have to choose between a vital security update and keeping your code working without a rewrite.
It's possible to create an annotation like #deprecated, I mean, with deprecated code-style?
I'd like to create an annotation to indicates that some messages were removed from the communication protocol, so I'd not want to use the deprecated annotation because I want 1) give a better and more suggestive name for my annotation, like "message removed" 2) give parameters for my annotation, e.g. (protocol = 5) -removed since protocol 5.
But, I want to keep this strikethrough code for others know that this message has been removed just by looking to the code.
#Deprecated annotation is designed for the development environment (generally but not only). It does nothing itself. But for IDE it is the some kind of marker and when it "see" that annotation - it performs some logic (for example "strikethrough" the code). The goal of my post is to tell that it is not enough to develop and use the annotation : it must me supported by environment.
There are two things you can do:
Add the
#Deprecated annotation to the method, and
Add a
#deprecated tag to the javadoc of the method
You should do both!
Quoting the java documentation on this subject:
Starting with J2SE 5.0, you deprecate a class, method, or field by using the #Deprecated annotation. Additionally, you can use the #deprecated Javadoc tag tell developers what to use instead.
Using the annotation causes the Java compiler to generate warnings when the deprecated class, method, or field is used. The compiler suppresses deprecation warnings if a deprecated compilation unit uses a deprecated class, method, or field. This enables you to build legacy APIs without generating warnings.
You are strongly recommended to use the Javadoc #deprecated tag with appropriate comments explaining how to use the new API. This ensures developers will have a workable migration path from the old API to the new API
When looking at the source code of the Deprecated annotation, you will see that there is nothing specific that makes it appear with the strikethrough. It is a feature of the IDE to mark #Deprecated code with a strikethrough.
Here it is:
#Documented
#Retention(RetentionPolicy.RUNTIME)
public #interface Deprecated {
}
+1 for oleg.lukyrych's answer BUT you can still do something.
Create your annotation (with all the parameters you want), then add a static code analysis to your build procedure. i.e. PMD with a custom rule. PMD is well know and well integrated in various IDE and continuous build environment like hudson/jenkins. The analysis will produce you a nice report of the (mis)use of your deprecated message.
It is not as nice as having it into your editor but it make the job.
Hope this helps.
Mayur Gupta,
I created a annotation MessageRemoved:
public #interface MessageRemoved {
Protocol protocol();
}
And a Enum:
public enum Protocol {
P01, P02, P03, P04, P05
}
Using a Annotation:
#MessageRemoved(protocol = Protocol.P05)
public class OldMessage extends Message{
}
This facilitates the traceability of messages removed. Using only annotation #Deprecated this is not possible.
Netbeans provides a lot of custom "hints", which are like warnings, only that most of them can't be suppressed (just disabled IDE-globally).
But now I looking at code which uses
#SuppressWarnings("element-type-mismatch")
to suppress a hint/warning which is called "suspicious method call" (such as remove(...) for a collection with a "wrong" type).
Well, I would never come to the idea to suppress a hint named "suspicious method call" with a SuppressWarnings-parameter called "element-type-mismatch", but apparently, it works.
So, is there a "magic list" of such parameters?
How, for instance, do I suppress the hint/warning "return of collection field"?
NOTE: for this similar question, "element-type-mismatch" is not listed.
After a brief look at the NB-sourcecode, I found these in some of the java.hint -classes:
#Hint(category="bitwise_operations", suppressWarnings="IncompatibleBitwiseMaskOperation")
#Hint(category="initialization", suppressWarnings="LeakingThisInConstructor")
#Hint(category="logging", suppressWarnings={"NonConstantLogger"}) //NOI18N
#Hint(category="logging", suppressWarnings={"ClassWithMultipleLoggers"}) //NOI18N
#Hint(category="logging", suppressWarnings={"ClassWithoutLogger"}, enabled=false) //NOI18N
#Hint(category="code_maturity", suppressWarnings="UseOfObsoleteCollectionType")
#Hint(category="initialization", suppressWarnings="OverridableMethodCallInConstructor")
#Hint(category="bitwise_operations", suppressWarnings="PointlessBitwiseExpression")
#Hint(category="code_maturity", suppressWarnings="CallToThreadDumpStack")
#Hint(category="bitwise_operations", suppressWarnings="ShiftOutOfRange")
#Hint(category="initialization", suppressWarnings="StaticNonFinalUsedInInitialization")
#Hint(category="code_maturity", enabled = false, suppressWarnings="UseOfSystemOutOrSystemErr")
#Hint(category="code_maturity", suppressWarnings="CallToPrintStackTrace")
Apparently, not all IDE-hints that are displayed as warnings are made suppressable...
Don't know why though, 'cause the AbstractHint class wich many of them extends easily provides this ability...
These are just the suppress-names though, so to find the mapping to the names of the warnings they represent, a deeper dig in the source is needed.
The documentation says:
Compiler vendors should document the warning names they support in conjunction with this annotation type. They are encouraged to cooperate to ensure that the same names work across multiple compilers.
Since NetBeans is using javac I think, here is a list.
See also this question.
If you are using another compiler, or some compiler plugin, search for its documentation.
Well the list is hard to find. Did find the sources of the hint classes of Netbeans.
So the 'list' is here. (also look at the sub packages; e.g. jdk and perf)
All classes can be supressed by using its camel cases name like:
// org.netbeans.modules.java.hints.jdk.UnnecessaryBoxing.java
#SuppressWarnings("UnnecessaryBoxing")
I have a deprecated method in my class:
#Deprecated
public void deprecatedMethod() {
//do bad things
}
I don't want that method to appear in the javadoc.
I know there's an option called -nodeprecated which:
"Prevents the generation of any
deprecated API at all in the
documentation."
So I'm using this option and it doesn't exclude the method from javadoc. Is it a bug in javadoc or am I using it wrong? What else can I do?
(I'm using eclipse 3.4.2 to produce javadoc)
You have to include "-nodeprecated" option in the Export to javadoc wizard.
Warning: it is a javadoc option, not a VM option.
I've tested it in Eclipse 3.4 and it worked.
Edit: If you only include Deprecated annotation it doesn't work. You have to include #deprecated tag inside method javadoc as well.
I don't know if there's a way to tell javadoc to use #Deprecated anotation (which curiously doesn't have a message parameter to document why is deprecated and what else to use).
Edit: before-1.5 way of deprecate methods
You have to include a #deprecated tag (or indicator or whatever) with the message you want to display to the user in the javadoc after the "deprecated".
/**
This method sets the property A.
#see getA
#author helios
#deprecated This method is not sync safe, use setAOk instead
*/
public void setA(String value) ...
#helios
john is saying that you must include the #deprecated javadoc tag within the javadoc comment block (/** ... */) as he has done above with:
#deprecated This method is not sync safe, use setAOk instead
Add this, then use the -nodeprecated option when running javadoc and the methods will not appear in the generated doc.