Since JSR 305 (whose goal was to standardize @NonNull and @Nullable) has been dormant for several years, I'm afraid there is no good answer. All we can do is to find a pragmatic solution and mine is as follows:
Syntax
From a purely stylistic standpoint I would like to avoid any reference to IDE, framework or any toolkit except Java itself.
This rules out:
- android.support.annotation
- edu.umd.cs.findbugs.annotations
- org.eclipse.jdt.annotation
- org.jetbrains.annotations
- org.checkerframework.checker.nullness.qual
- lombok.NonNull
Which leaves us with either javax.validation.constraints or javax.annotation.
The former comes with JEE. If this is better than javax.annotation, which  might come eventually with JSE or never at all, is a matter of debate.
I personally prefer javax.annotation because I wouldn't like the JEE dependency.
This leaves us with
javax.annotation
which is also the shortest one.
There is only one syntax which would even be better: java.annotation.Nullable. As other packages graduated
from javax to java in the past, the javax.annotation would
be a step in the right direction.
Implementation
I was hoping that they all have basically the same trivial implementation,
but a detailed analysis showed that this is not true.
First for the similarities:
The @NonNull annotations all have the line
public @interface NonNull {}
except for
- org.jetbrains.annotationswhich calls it- @NotNulland has a trivial implementation
- javax.annotationwhich has a longer implementation
- javax.validation.constraintswhich also calls it- @NotNulland has an implementation
The @Nullable annotations all have the line
public @interface Nullable {}
except for (again) the org.jetbrains.annotations with their trivial implementation.
For the differences:
A striking one is that
- javax.annotation
- javax.validation.constraints
- org.checkerframework.checker.nullness.qual
all have runtime annotations (@Retention(RUNTIME)), while
- android.support.annotation
- edu.umd.cs.findbugs.annotations
- org.eclipse.jdt.annotation
- org.jetbrains.annotations
are only compile time (@Retention(CLASS)).
As described in this SO answer the impact of runtime annotations
is smaller than one might think, but they have the benefit
of enabling tools to do runtime checks in addition to the
compile time ones.
Another important difference is where in the code the annotations can be used.
There are two different approaches. Some packages use JLS 9.6.4.1 style contexts. The following table gives an overview:
| Package | FIELD | METHOD | PARAMETER | LOCAL_VARIABLE | 
| android.support.annotation | ✔️ | ✔️ | ✔️ |  | 
| edu.umd.cs.findbugs.annotations | ✔️ | ✔️ | ✔️ | ✔️ | 
| org.jetbrains.annotation | ✔️ | ✔️ | ✔️ | ✔️ | 
| lombok | ✔️ | ✔️ | ✔️ | ✔️ | 
| javax.validation.constraints | ✔️ | ✔️ | ✔️ |  | 
 
org.eclipse.jdt.annotation, javax.annotation and org.checkerframework.checker.nullness.qual use the contexts defined in
JLS 4.11, which is in my opinion the right way to do it.
This leaves us with
- javax.annotation
- org.checkerframework.checker.nullness.qual
in this round.
Code
To help you to compare further details yourself I list the code of every annotation below.
To make comparison easier I removed comments, imports and the @Documented annotation.
(they all had @Documented except for the classes from the Android package).
I reordered the lines and @Target fields and normalized the qualifications.
package android.support.annotation;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER})
public @interface NonNull {}
package edu.umd.cs.findbugs.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface NonNull {}
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NotNull {String value() default "";}
package javax.annotation;
@TypeQualifier
@Retention(RUNTIME)
public @interface Nonnull {
    When when() default When.ALWAYS;
    static class Checker implements TypeQualifierValidator<Nonnull> {
        public When forConstantValue(Nonnull qualifierqualifierArgument,
                Object value) {
            if (value == null)
                return When.NEVER;
            return When.ALWAYS;
        }
    }
}
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf(MonotonicNonNull.class)
@ImplicitFor(
    types = {
        TypeKind.PACKAGE,
        TypeKind.INT,
        TypeKind.BOOLEAN,
        TypeKind.CHAR,
        TypeKind.DOUBLE,
        TypeKind.FLOAT,
        TypeKind.LONG,
        TypeKind.SHORT,
        TypeKind.BYTE
    },
    literals = {LiteralKind.STRING}
)
@DefaultQualifierInHierarchy
@DefaultFor({TypeUseLocation.EXCEPTION_PARAMETER})
@DefaultInUncheckedCodeFor({TypeUseLocation.PARAMETER, TypeUseLocation.LOWER_BOUND})
public @interface NonNull {}
For completeness, here are the @Nullable implementations:
package android.support.annotation;
@Retention(CLASS)
@Target({METHOD, PARAMETER, FIELD})
public @interface Nullable {}
package edu.umd.cs.findbugs.annotations;
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
@Retention(CLASS)
public @interface Nullable {}
package org.eclipse.jdt.annotation;
@Retention(CLASS)
@Target({ TYPE_USE })
public @interface Nullable {}
package org.jetbrains.annotations;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface Nullable {String value() default "";}
package javax.annotation;
@TypeQualifierNickname
@Nonnull(when = When.UNKNOWN)
@Retention(RUNTIME)
public @interface Nullable {}
package org.checkerframework.checker.nullness.qual;
@Retention(RUNTIME)
@Target({TYPE_USE, TYPE_PARAMETER})
@SubtypeOf({})
@ImplicitFor(
    literals = {LiteralKind.NULL},
    typeNames = {java.lang.Void.class}
)
@DefaultInUncheckedCodeFor({TypeUseLocation.RETURN, TypeUseLocation.UPPER_BOUND})
public @interface Nullable {}
The following two packages have no @Nullable, so I list them separately; Lombok has a pretty boring @NonNull.
In javax.validation.constraints the @NonNull is actually a @NotNull
and it has a longish implementation.
package lombok;
@Retention(CLASS)
@Target({FIELD, METHOD, PARAMETER, LOCAL_VARIABLE})
public @interface NonNull {}
package javax.validation.constraints;
@Retention(RUNTIME)
@Target({ FIELD, METHOD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Constraint(validatedBy = {})
public @interface NotNull {
    String message() default "{javax.validation.constraints.NotNull.message}";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default {};
    @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
    @Retention(RUNTIME)
    @Documented
    @interface List {
        NotNull[] value();
    }
}
Support
From my experience, javax.annotation is at least supported by Eclipse and the Checker Framework out of the box.
Summary
My ideal annotation would be the java.annotation syntax with the Checker Framework implementation.
If you don't intend to use the Checker Framework the javax.annotation (JSR-305) is still your best bet for the time being.
If you are willing to buy into the Checker Framework just use
their org.checkerframework.checker.nullness.qual.
Sources
- android.support.annotationfrom- android-5.1.1_r1.jar
- edu.umd.cs.findbugs.annotationsfrom- findbugs-annotations-1.0.0.jar
- org.eclipse.jdt.annotationfrom- org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
- org.jetbrains.annotationsfrom- jetbrains-annotations-13.0.jar
- javax.annotationfrom- gwt-dev-2.5.1-sources.jar
- org.checkerframework.checker.nullness.qualfrom- checker-framework-2.1.9.zip
- lombokfrom- lombokcommit- f6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
- javax.validation.constraintsfrom- validation-api-1.0.0.GA-sources.jar