How to use @Nullable and @Nonnull annotations more effectively?

package annotation does not exist
multiple annotations of type androidx annotation nullable
android annotation dependencies
package org androidannotations annotations rest does not exist
annotation annotation
nullable android
nonnull annotation android
import androidx annotation nullable cannot be resolved

I can see that @Nullable and @Nonnull annotations could be helpful in preventing NullPointerExceptions but they do not propagate very far.

  • The effectiveness of these annotations drop off completely after one level of indirection, so if you only add a few they don't propagate very far.
  • Since these annotations are not well enforced there is a danger of assuming a value marked with @Nonnull is not null and consequently not performing null checks.

The code below causes a parameter marked with @Nonnull to be null without raising any complaints. It throws a NullPointerException when it is run.

public class Clazz {
    public static void main(String[] args){
        Clazz clazz = new Clazz();

        // this line raises a complaint with the IDE (IntelliJ 11)
        clazz.directPathToA(null);

        // this line does not
        clazz.indirectPathToA(null); 
    }

    public void indirectPathToA(Integer y){
        directPathToA(y);
    }

    public void directPathToA(@Nonnull Integer x){
        x.toString(); // do stuff to x        
    }
}

Is there a way to make these annotations more strictly enforced and/or propagate further?

Short answer: I guess these annotations are only useful for your IDE to warn you of potentially null pointer errors.

As said in the "Clean Code" book, you should check your public method's parameters and also avoid checking invariants.

Another good tip is never returning null values, but using Null Object Pattern instead.

Improve code inspection with annotations, To learn more, read Use the annotation processor dependency the Android @ Nullable and @NonNull annotations in detected locations in your code. Android null annotations so the Lint checker can properly notify you� @Nullable and @NotNull annotations let you check nullability of a variable, parameter, or return value. They help you control contracts throughout method hierarchies, and if IntelliJ IDEA spots that the contract is being violated, it will report the detected problem, and will point to the code where NullPointerException may occur.

Using null annotations, The down-side: the analysis can not "see" which values (null or non-null) are When using 3rd party null annotations, please ensure that those are properly It should be clear now that null annotations add more information to your Java� The primary argument against using @Nonnull is that it will effectively require an annotation on every field, method parameter/type, and local variable. Nullable types should be a rare exception in our codebase, such that @Nonnull should be the default.

I think this original question indirectly points to a general recommendation that run-time null-pointer check is still needed, even though @NonNull is used. Refer to the following link:

Java 8's new Type Annotations

In the above blog, it is recommended that:

Optional Type Annotations are not a substitute for runtime validation Before Type Annotations, the primary location for describing things like nullability or ranges was in the javadoc. With Type annotations, this communication comes into the bytecode in a way for compile-time verification. Your code should still perform runtime validation.

(PDF) Non-null References by Default in Java: Alleviating the Nullity , For such tools to be truly effective, they require that developers annotate code bases that the use of non-null annotations is more labor intensive than it should be. Keywords: non-null annotations, non-null types, Java, JML, nullity default. There is no standard @NonNull annotation. Creating such an annotation was the goal of JSR 305, which has been abandoned for a long time. There will not be a standard @NonNull annotation until JSR 305 is reconstituted. Oracle has no current plans to do so. (JEE annotations are outside the scope of JSR 305.)

Compiling the original example in Eclipse at compliance 1.8 and with annotation based null analysis enabled, we get this warning:

    directPathToA(y);
                  ^
Null type safety (type annotations): The expression of type 'Integer' needs unchecked conversion to conform to '@NonNull Integer'

This warning is worded in analogy to those warnings you get when mixing generified code with legacy code using raw types ("unchecked conversion"). We have the exact same situation here: method indirectPathToA() has a "legacy" signature in that it doesn't specify any null contract. Tools can easily report this, so they will chase you down all alleys where null annotations need to be propagated but aren't yet.

And when using a clever @NonNullByDefault we don't even have to say this every time.

In other words: whether or not null annotations "propagate very far" may depend on the tool you use, and on how rigorously you attend to all the warnings issued by the tool. With TYPE_USE null annotations you finally have the option to let the tool warn you about every possible NPE in your program, because nullness has become an intrisic property of the type system.

(PDF) Reducing the use of nullable types through non-null by , the use of non-null annotations is more labor intensive than it should be. effective too), a simple solution seemed apparent: switch the nullity interpretation of. The answer is two-fold. For @NonNull and @Nullable do the following: If you use androidx you need to add. implementation 'androidx.annotation:annotation:1.0.2' or if you use the legacy support library (your imports are for this version) implementation 'com.android.support:support-annotations:28.0.0' to your dependencies in the build.gradle file

I agree that the annotations "don't propagate very far". However, I see the mistake on the programmer's side.

I understand the Nonnull annotation as documentation. The following method expresses that is requires (as a precondition) a non-null argument x.

    public void directPathToA(@Nonnull Integer x){
        x.toString(); // do stuff to x        
    }

The following code snippet then contains a bug. The method calls directPathToA() without enforcing that y is non-null (that is, it does not guarantee the precondition of the called method). One possibility is to add a Nonnull annotation as well to indirectPathToA() (propagating the precondition). Possibility two is to check for the nullity of y in indirectPathToA() and avoid the call to directPathToA() when y is null.

    public void indirectPathToA(Integer y){
        directPathToA(y);
    }

Non-null References by Default in Java: Alleviating the Nullity , the use of non-null annotations is more labor intensive than it should be. that simple techniques are effective too), a simple solution seemed apparent: switch. The @nonnull annotation can be seen as a precondition that is used for static analysis by the tool FindBugs. If you prefer an approach such as runtime-assertion checking, i.e. the fail first strategy, you should consider using assertion statements as built-in Java.

[PDF] Towards Support for Non-null Types and Non-null-by , effective, they require that developers annotate declarations with nullity modifiers. that the use of non-null annotations is more labor intensive than it should be. How to use @Nullable and @Nonnull annotations more effectively? (6) I can see that @Nullable and @Nonnull annotations could be helpful in preventing NullPointerExceptions but they do not propagate very far.

Using null type annotations, Starting with Java 8, null annotations can be used in a new and more powerful Use a @NonNull upper bound for constraining type arguments to nonnull types. Properly designed annotation types can be distinguished by looking at their� add @Nullable annotations for existing code only if needed or changes are done at the code. So, no need to start reading all interfaces and classes and add it just to use it on every place use the code as it has been annotated by @NonNullByDefault. That is the suggested way of using the annotations and some checkers use this default

Handling Nullability in Android 11 and , The @Nullable annotation ensures that when using the result of SDK with more @RecentlyNullable and @RecentlyNonNull annotations on� The @NonNullFields annotation is generally preferable to @NonNull as it helps reduce boilerplate. At times we want to exempt some fields from the non-null constraint specified at the package level. At times we want to exempt some fields from the non-null constraint specified at the package level.

Comments
  • I like the idea of @Nullable or @Nonnull, but if they are worth it is very "likely to solicit debate"
  • I think the way to move to a world where this causes a compiler error or warning is to require a cast to @Nonnull when calling an @Nonnull method with a nullable variable. Of course, casting with an annotation is not possible in Java 7, but Java 8 will be adding the ability to apply annotations to the use of a variable, including casts. So this may become possible to implement in Java 8.
  • @TheodoreMurdock, yes, in Java 8 a cast (@NonNull Integer) y is syntactically possible, but a compiler is not allowed to emit any specific byte code based on the annotation. For runtime assertions tiny helper methods are sufficient as discussed in bugs.eclipse.org/442103 (e.g., directPathToA(assertNonNull(y))) - but mind you, this only helps to fail fast. The only safe way is by performing an actual null check (plus hopefully an alternative implementation in the else branch).
  • It would be helpful in this question to say which @Nonnull and @Nullable you are talking about, as there are multiple similar annoations (See this question). Are you talking about the annotations in package javax.annotation?
  • @TJamesBoone For the context of this question it does not matter, this was about how to use any of them effectively.
  • For return values possibly being empty, I strongly suggest using the Optional type instead of plain null
  • Optional ist not better, than "null". Optional#get() throws NoSuchElementException while a usage of the null throws NullPointerException. Both are RuntimeException's without meaningful description. I prefer nullable variables.
  • @30thh why would you use Optional.get() directly and not Optional.isPresent() or Optional.map first?
  • @GauravJ Why would you use a nullable variable directly and not check, if it null first? ;-)
  • The difference between Optional and nullable in this case is that Optional better communicates that this value can intentionally be empty. Certainly, it's not a magic wand and in the runtime it may fail exactly the same way as nullable variable. However, API reception by programmer is better with Optional in my opinion.
  • I sympathize with the OP here, because even though you cite these two advantages, in both cases you used the word "can." That means that there is no guarantee that these checks will actually occur. Now, that behavioral difference could be useful for performance-sensitive tests that you'd like to avoid running in production mode, for which we have assert. I find @Nullable and @Nonnull to be useful ideas, but I'd like more force behind them, rather than us hypothesizing about what one could do with them, which still leaves open the possibility of doing nothing with them.
  • The question is where to begin. At the moment his anntations are optional. Somtimes I would like it if they were not because in some circumstances it would be helpful to enforce them...
  • May I ask what is AOP you're referring here?