Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I mark both the interface and its implementation with the @NonNull annotation?

In the interface that describes the service, I have methods similar to this:

TaskCard saveTaskCard(@NonNull TaskCard card, User user);

I put the @NonNull (lombok) annotation before an argument, but it won't work on its own if the same annotation isn't in the implementation. This means that in the methods of the class implementing this interface, I will need to put this annotation again, thereby duplicating the code.

@Override
@Transactional
public TaskCard saveTaskCard(@NonNull TaskCard taskCard, User user) {
    taskCard.setUser(user);
    return repository.save(taskCard);
}

The question is, is this how it should be? If you put this annotation only in the interface, they will not work, and if you put it only in the class that implements the interface, then API users may not understand that null cannot be passed to these methods. What should I do?

like image 271
NarasuOo Avatar asked Jun 17 '20 18:06

NarasuOo


People also ask

What does the @NotNull annotation do?

@NotNull The @NotNull annotation is, actually, an explicit contract declaring that: A method should not return null. Variables (fields, local variables, and parameters) cannot hold a null value.

How does @NonNull work?

A @NonNull on a primitive parameter results in a warning. No null-check will be generated. A @NonNull on a parameter of an abstract method used to generate a warning; starting with version 1.16. 8, this is no longer the case, to acknowledge the notion that @NonNull also has a documentary role.

Can an annotation implement an interface?

From the Annotations Reference: Return types are restricted to primitives, String, Class, enums, annotations, and arrays of the preceding types. So, yes, the type can be an enum that implements an interface, but not the interface itself.

Which annotation can be used to ensure that an interface?

You can annotate with @Service an implementation and autowire the interface. Spring will check for any object implementing this interface.


1 Answers

IMHO you surely should duplicate it for the reasons you stated:

  • put it on the interface so that user see it
  • put it on the implementation so that Lombok can check it

It's only redundant, when you don't consider that nullability is actually part of the type - not in Java, but it reality (and e.g., Kotlin), it is.

Unfortunately, Lombok can't do any better and it can access the interface (not parent class).

There are tools which may help you do this consistently (but I haven't tried them yet) or you can write a simple reflection-based test. Then, you'll still be forced to write redundant stuff, but you'll be reminded if you forget.

like image 147
maaartinus Avatar answered Sep 30 '22 10:09

maaartinus