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.
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.
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 ask why are the java annotations used so much... I know that they replaced xml configuration in for example jpa, but why is this kind configuration used at all?
Consider this piece of code:
#Entity
class Ent{
// some fields
}
//... somewhere in the other file far far away
class NonEnt{
// whatever here
}
Now, when I try to put this in persistence context, with EntityManager's persist method, I get runtime error(better would be to get compile error) with trying to persist NonEnt instance. There is obvious solution for me, force the entities to implement some no-method interface instead of using #Annotations. But this isn't popular among framework designer, what is the drawback of this solution?
Thanks for answering...
When compared to marker interfaces, annotations have some advantages:
they can be parameterized
they are more fine grained - you can attach them not only to classes but also to other class elements (fields, methods, method arguments, etc)
Annotations are also supposedly less intrusive, but this point is matter of taste and debatable.
See also:
Annotations (official JDK documentation)
What is the use of marker interfaces in Java?
The use of annotations is a lot less invasive than forcing the client to implement a interface or extend a class.
There is obvious solution for me,
What you describe is called a "marker interface" and it's an abuse of the interface concept. I suspect the only reason why you consider it obvious is because of Serializable - which only exists because there were no annotations at that time.
force the entities to implement some
no-method interface instead of using
#Annotations. But this isn't popular
among framework designer, what is the
drawback of this solution?
What are its advantages? Annotations have the huge advantage that they can have parameters, and they are much more fine-grained. Marker interfaces only work at the class level.
Citing the java tutorial:
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Annotations have a number of uses,
among them:
Information for the compiler — Annotations can be used by the
compiler to detect errors or suppress
warnings.
Compiler-time and deployment-time processing — Software tools can
process annotation information to
generate code, XML files, and so
forth.
Runtime processing — Some annotations are available to be
examined at runtime.
As you can see, annotations are a way of specifying meta-data about your types in java, including interfaces, they are in no way a replacement for them.
Java annotation are really helpful when you want to add some additional information to your class, method or instance variable. There are a lot of libraries which use these annotations heavily. These annotations keep the code simple and readable with the power of making changes to the code at runtime.
For example if you have used lombok library, which creates setter, getter and constructor at compile time and saves you lines of code and time.
When compiler executes the code, lomok searches for all the fields marked with #Setter or #Getter annotation and add setter and getter for that field in the class.
One other example is Junit test runner. How junit differentiates between normal helper method in test class and a test. To differentiate between the two it uses #Test annotation.
This tutorial explains how you can use java annotations to create you own test runner.
I'm interested in finding out exactly which Java annotations people think are most useful during development. This doesn't necessarily have to limited to the core Java API, you may include annotations you found in third party libraries or annotations you've developed yourself (make sure you include a link to the source).
I'm really interested in common development tasks rather than knowing why the #ManyToOne(optional=false) in JPA is awesome...
Include the annotation and a description of why it's useful for general development.
I doled out a bunch of upvotes for other users, but just to give my two cents the only three annotations I use with any regularity in development are the main annotations used directly by the compiler:
#Override - Great for making it explicit in your code when you're overriding another method. Also has the extra benefit of being flagged as a compilation error if you don't override a method the way you think you are (see this other SO post). This flag informs the compiler that you're intending to override something, so if you don't (e.g. you forget an argument in the method signature), the compiler will catch it.
#Deprecated - Indicate whatever you're marking as something that should not be used from this point forward. The compiler will generate warnings for use of any code elements you've marked as deprecated. In general, deprecation says "this was in here in the past, but it may go away in a future version." Make sure you also use the associated "#deprecated" Javadoc flag in conjunction with this too to tell people what they should use instead.
#SuppressWarnings - Tell the compiler to suppress specific warnings it would otherwise generate. This can be useful for things like when you intentionally want to use deprecated methods, you can block out the deprecation warning. I tend to use it a lot to block out everyone's favorite "Serialization UID" warning on serializable classes (whether or not you should do that is another debate for another time). Just handy for those cases where you know something you're doing is generating a warning, but you're 100% sure it's the proper behavior you want.
Look at the Sun Annotations Guide and check out the section "Annotations Used by the Compiler". These three are given a fairly lengthy discussion.
The Java Concurrency in Practice annotations
Very useful for describing exactly how your code is or isn't thread safe...
I find the he concurrency-related annotations defined by Brian Goetz in his book "Java Concurrency In Practice" to be very useful:
#GuardedBy
#Immutable
#NotThreadSafe
#ThreadSafe
They're particularly useful as FindBugs has patterns that use them.
A jar and documentation is freely available at http://www.javaconcurrencyinpractice.com/
#Override has my vote. It makes it instantly clear what your method is about and makes your code more readable.
#Test
(JUnit 4) It's made writing and understanding test files quite a bit cleaner. Plus, the ability to add the expected attribute has saved a few lines of code here and there.
#Deprecated
Introduced in Java 5.
It helps developers see what's deprecated in IDEs. (Prior to this, most IDEs could still pull a #deprecated out of the javadoc comments for a particular method, but this annotation was a nice way to make it meta-information about the method itself, rather than a comment in documentation.)
It's also used by the compiler to print out warnings when you're using deprecated methods.
Personally I've been looking at the JSR303 Bean Validation and the annotations it provides, I imagine these will become more commonplace, there's only a few implementations of the JSR so far, but they provide annotations such as:
#NotNull private String name;
#NotNull #Size(min = 5, max = 30) private String address;
More info here: http://jcp.org/en/jsr/detail?id=303
these should be useful, you can define them in your projects to better communicate intentions:
#ThreadSafe
#Immutable
#ValueObject
#BagOfFunctions (e.g. java.util.Collections)
etc
Here are some Annotations I use in day to day development
Spring:
#Autowired - used to Auto wire beans
#Rollback - If set to true it will rollback all DB operations done inside the test case
JUnit:
#Test - Tell that a method is a test case
#Ignore - If you want to ignore any of the test cases
#Before - Code that should run before each test case
JPA:
#Entity - To tell that a POJO is a JPA Entity
#Column - Map the property to DB column
#Id - tell that a java property is Primary key
#EmbeddedId - Used for Composite Primary Keys
#Transient - This property should not be persisted
#Version - Used to manage optimistic locking
#NamedQuery - Used to declare Native SQLs
#OneToMany - One to Many relationship
#ManyToOne - Many to one Relationship
I have included only the most essential ones.You can find details about all the JPA annotations from the following links.
http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html
http://www.hiberbook.com/
We started using a compile time tool called lombok (http://projectlombok.org/). You annotate classes, members, etc. and methods are automatically generated at compile time. It's a great productivity boost and saves hundreds of lines of tedious coding.
Do you want a toString() method to be automatically generated? Just annotate your class with #ToString.
Tired of having to define getters and setters for your members? Annotate your class with #Getter and / or #Setter and they're automatically added.
Want to have an SLF4J logger to log stuff? #Slf4j creates a private static final logger for you.
#Data
public class MyBean {
// Getters for x and y, setter for y and constructor with x as arg automatically created!
// toString() and hashCode() methods are there too!
private final int x;
private int y;
}
.
#Slf4j
public class SomeClass {
public void doSomething() {
log.info("I've got log.");
}
}
Setting it up is very easy: just add a provided maven dependency. There's also a tiny Eclipse / IntelliJ plugin.
Check out the full list of features there: http://projectlombok.org/features/index.html
Junit 4 provides very useful annotations. Here's a tutorial illustrating the usage of annotations to define tests.
e.g.
#Test(expected= IndexOutOfBoundsException.class) public void empty() {
new ArrayList<Object>().get(0);
}
As Dan pointed out below, TestNG did this originally.
#Given
allows one JUnit test to build upon the return value of another test. Requires JExample.
#FunctionalInterface
Useful to communicate that a particular interface is meant to be functional. If the single abstract method is removed, it'll throw a compilation error.
I started a weekend project to implement a Programming By Contract framework using method and parameter annotations e.g.
//...
myMethod (#NotNull String a, #NotNullOrEmpty String b){
if ( !validate() ){
//raiseException
}
}
I got stuck at the point of getting param values automatically. Java reflection does not have it. never understood several people's ranting on Java till I came across this limitation.