When is it appropriate to annotate something as #NotNull in Java? - java

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.

Related

Lombok's #NonNull or javax #Nonnull

Lombok's #NonNull VS javax.annotation.Nonnull
Which one is better to use for method parameters and when?
The answer here vaguely compares all annotations but has no inference on which one is best. I just to know the better of the two.
javax.annotation.Nonnull is part of JSR-305 which seems to be dead. Even if that wasn't the case said annotation would have only be used for static code analysis purposes, e.g. your IDE warning you that you're passing in a null value someplace where this is not acceptable.
lombok.NonNull is a very different story. First of all, said annotation is NOT used for validation purposes or rather static code analysis purposes. Lombok uses this annotation to fire NPEs whenever an instance variable or a parameter are null when they're not supposed to.
Lombok, being an annotation post processor will effectively pick up this annotation during the pre-compilation process and will auto generate the needed code to effectively handle these cases (by manipulating the AST).
You can read more on this here: Lombok - NonNull.
It seems that your familiarity with both the javax.annotation related functionality and Lombok's functionality is not the best, so I would suggest to have a good read on what is what.

Alternatives to #Deprecated SerializationFeature.WRITE_EMPTY_JSON_ARRAYS

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.

What is the advantage of annotating an immutable Java class with #Immutable?

I get the concept of immutability, and why it is a good idea to make DTOs immutable.
I also notice that Java has an #Immutable annotation that we can use to annotate immutable classes.
My question is: what does annotating a Java class as #Immutable give us? Are there any library features that only work on classes annotated in this way?
The annotation documents the fact that your class is immutable and tells the users of the class that you have followed the contract defined in the annotation javadoc. It is also frequent to simply include a comment directly in the javadoc: this is the approach chosen by the JDK, see for example the javadoc of LocalDate.
Some static analysis tools such as FindBugs can also use that annotation and verify that the class really is immutable. If you forgot to make a public field final for example, FindBugs will emit a warning.
The main benefit is documentation. The JCIP annotations were introduced without implementations, on the theory that they offered documentation benefits from being written even if they were not checked.
I do not know of any current library feature that depends on your class being annotated as #Immutable.
There are two ways that existence of an #Immutable annotation could potentially affect your program.
At compile time, your program could fail to compile because it did not respect the library's contract -- in other words, the compiler issues a warning if your program contains an immutability bug. This is how the Checker Framework's IGJ Immutability Checker works. Alternately, you could run an additional analysis at build time and fail the build if the analysis fails. This is how FindBugs works (also see MutabilityDetector4FindBugs, a third-party add-on).
At run time, the library could use reflection or a similar analysis to read your program's classfiles. The library could behave differently (such as throwing an error) depending on whether it finds #Immutable annotations.
A caution: there are multiple, equally valid definitions of #Immutable, and it's easy to mix them up which leads to confusion. For instance, is the immutability with respect to the Java heap (no changes whatsoever are permitted to any field), or with respect to the abstract value (internal representation changes are permitted so long as no client can observe them)? As another example, is the immutability shallow (no changes to this object, but changes are permitted to objects it references) or transitive (no changes to this object or to any object that it references)? Does the immutability prevent changes through the given reference or variable, or does it also prevent changes through aliases? Be sure that you understand what choices your tool has made.
what does annotating a Java class as #Immutable give us?
Annotation in Java does not do anything itself, but they are used by external tools. Take a look at very good inspections for such annotations in IntelliJ IDEA.

Guava Optional versus Bean Validation

We are implementing a new Java EE Project and are not very familiar with this technology so far. So we much have to learn...
Currently we are using Guava Optional in BOs to implement fields that are not mandatory.
We have a lot of discussion around this class and I don't see the advantages so far. I would prefer to using Bean Validation with the annotation #NotNull to indicate if a field is set always or not. Of course, that it's set, you can only be sure after validation.
Now to my question. Does eclipse don't show the Bean Validation Annotations? So you would better see, what you can be sure. Is there a plugin that would help?
Guava/Java 8 Optional should be used to enforce the following convention: if, according to bussiness logics, some function might return null value, then we wrap it inside Optional, so our intention is clear - users has to check for value presence. If a function returns non-optional object, we assume that is never can be null and users of that function do not have to do null checks. Hence the code will be much cleaner.
Since Optional is a part of Java 8 now, I guess this will become standard approach to handle nulls.
Some IDEs provide special annotation for the sake of showing hints. Eclipse has #NonNull annotation, similarly IntelliJ IDEA has #Nullable/#NotNull annotations, but they have nothing to do with Bean Validation annotation.

I want to know if it is possible to create a Java Annotation that enforces a specific Return Type?

I want to know if it is possible to create an Annotation that enforces a specific Return Type?
What I would like is a way to create an Annotation and use it like:
#MarkerAnnotationForcingStringReturnType
public String someWebflowMethod(...){
...
return "someString";
}
Then I can have any method name I want, but it will have to return, a String, for example.
Doesn't the method signature itself enforce a specific return type?
You could create your own annotation and then write your own annotation processor which could enforce it.
I don't know of one built in... and frankly I'm not sure I see the point. If you're going to be vigilant enough to write the annotation, why would you not be vigilant enough to get the method return type right? Under what circumstances would you get the annotation right but the method wrong?
By themselves, annotations are simply metadata - that is, "comments" that are attached to bits of code and are included in the bytecode itself (possibly).
You could write a processor using apt that would validate this at compile-time if you really wanted to.
But I find that declaring a method to return String is just as robust and more easily understandable by a typical Java developer. Do you really have a good reason for doing this? If you're worried that someone might change the return type, they might just as easily delete your annotation. If you want to prevent someone from making these changes, a comment is arguably more effective than an annotation that they might remove for "being superfluous" (hey, we're talking about developers that you're expecting to invalidate base requirements here through incompetence/lack of awareness...).

Categories