Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android @NonNull usefulness

After a few reading and questions like this one I was wondering if there was a point in using @NonNull Android Support Annotation.

I can see a very small warning from Android Studio if I attempt to call a method with a null parameter that is annotated as @NonNull. Just a warning??

What about Unit Testing ? Should I test the method with a null paramter? If I do ... I will get a NullPointerException and my test will fail.

Let's say we are two developers. One working on the API and one testing the API in all kind of manners. As the second developer, it's my responsibility to test everything so that the API is bullet-proof. That's the whole point of Unit Testing, right ?

So then ... what's the point of the first developer using @NonNull ?

If someone else were to use this API with a null parameter ... then the API would throw a NPE. He then would think : "Urg, that API sucks... NPE !" and he would be right. That naughty dev for not checking if the parameter he sent is null or not should be faced with an IllegalArgumentException because it's his fault not that of the API's!

Am I wrong ?

I thought these annotations would enforce the compiler to show errors like attempting to call methodName(@NonNull Object object) with null parameter.

Update 1

Alright thank you all for your comments. I'd like to summ up if possible regarding the "issue" I am facing here. In an abstract way.

I write some code (an API, a Library, a Class, whatever) with private internal code wrapped by public methods that provides features.

Assume these public methods will be used by anyone else (including me). Some of them take arguments that must never be null or else all hell breaks loose.

Reading your comments, I am facing the following options :

  1. Keep on using contracts / annotations (@NonNull) supported by Java Documentation stipulating parameter must not be null. Don't check for null parameters (or else IDE will warn me) and, somehow, pray that I will never receive a null parameter ;
  2. Same as above, but enforce a null check (even though IDE will warn that condition will always be false) and throw IllegalArgumentException instead of causing an NPE in case I receive a null parameter ;
  3. Stop using contracts / annotations, use Java Doc to warn others dev and add manual check for all parameters.

Finally, for unit testing ... I know I can not have bullet-proof code, but I like to "monkey-test" my code as much as possible to prevent unexpected behavior from my code as well to validate the process (which is at the base of Unit Testing, I believe)-

like image 269
Mackovich Avatar asked Feb 24 '16 14:02

Mackovich


People also ask

What is@ NonNull in Android?

Denotes that a parameter, field or method return value can never be null. This is a marker annotation and it has no specific attributes.

What is NonNull java?

The nonNull method is a static method of the Objects class in Java that checks whether the input object reference supplied to it is non-null or not. If the passed object is non-null, then the method returns true. If the passed object is null , then the method returns false.

What does @nullable mean Android?

The @Nullable annotation means that the given parameter or return value can be null, letting Android Studio warn you if you try to use a value that might be null without checking (such as our previous optional filter).

What is @nullable in Android Studio?

Denotes that a parameter, field or method return value can be null. When decorating a method call parameter, this denotes that the parameter can legitimately be null and the method will gracefully deal with it. Typically used on optional parameters.


2 Answers

Its main purpose is informational to your coworkers. One person is never the sole programmer of a large project. Using NotNull tells other programmers that the contract of the function means you can never send a null to it, so they don't do it. Otherwise I may make a logical assumption that calling setFoo(null) will clear Foo, whereas the API can't handle not having a Foo.

like image 159
Gabe Sechan Avatar answered Oct 20 '22 19:10

Gabe Sechan


Your #2 approach in my opinion is the correct way to do it for an API / Library. Use the annotation for static analysis to prevent compile-time attempts to call the method with null, and use a null check at runtime to give a useful exception (and to fail fast / protect from unexpected things from happening in your code) if a null object gets passed in. Use a //noinspection ConstantConditions directive before the null check to tell the IDE to suppress the warning (since you are checking null for a valid reason).

A random NPE indicates that the library/api author has possibly missed something and has a bug that isn't being handled in their code.

An IllegalArgumentException (or NPE with a description of the problem - which exception to use in this instance is an opinion-based argument) indicates that the caller has made a mistake in the way they called the method.

Ultimately though, whether to test for null after you've already annotated with @NonNull is going to be opinion-based and situation-dependent.

like image 27
jt-gilkeson Avatar answered Oct 20 '22 17:10

jt-gilkeson