Yana JSR 305 (kimin gol standardize edilerek @NonNullve @Nullable) birkaç yıldır atıl sahiptir Korkarım hiç iyi bir cevap yoktur. Yapabileceğimiz tek şey pragmatik bir çözüm bulmak ve benimki şöyle:
Sözdizimi
Tamamen stilistik bir bakış açısından, IDE'ye, çerçeveye veya Java'nın kendisi dışında herhangi bir araç setine göndermekten kaçınmak istiyorum.
Bu kurallar:
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
org.checkerframework.checker.nullness.qual
lombok.NonNull
Hangi birini bize bırakır javax.validation.constraintsya javax.annotation. Birincisi JEE ile birlikte gelir. Bu, javax.annotationnihayetinde JSE ile gelebilecek ya da hiç gelmeyecek olandan daha iyiyse , bir tartışma konusudur. Şahsen tercih ediyorum javax.annotationçünkü JEE bağımlılığını sevmezdim.
Bu bizi
javax.annotation
ki bu da en kısa olanı.
Hatta daha iyi olurdu tek sözdizimi vardır: java.annotation.Nullable. Diğer paketler mezun olarak javaxhiç javageçmişte, javax.annotation doğru yönde atılmış bir adım olacaktır.
uygulama
Hepsinin temelde aynı önemsiz uygulamaya sahip olmasını umuyordum, ancak ayrıntılı bir analiz bunun doğru olmadığını gösterdi.
Birincisi benzerlikler için:
@NonNullEk açıklamalar, tüm çizgi var
public @interface NonNull {}
dışında
org.jetbrains.annotationski bu onu çağırıyor @NotNullve önemsiz bir uygulaması var
javax.annotation daha uzun bir uygulaması olan
javax.validation.constraintsbu da onu çağırır @NotNullve bir uygulaması vardır
@NullableEk açıklamalar, tüm çizgi var
public @interface Nullable {}
org.jetbrains.annotationsönemsiz uygulamalarıyla (tekrar) hariç .
Farklılıklar için:
Çarpıcı olanı
javax.annotation
javax.validation.constraints
org.checkerframework.checker.nullness.qual
hepsinde çalışma zamanı ek açıklamaları ( @Retention(RUNTIME)) bulunurken
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
yalnızca derleme zamanıdır ( @Retention(CLASS)).
Bu SO yanıtında açıklandığı gibi , çalışma zamanı ek açıklamalarının etkisi düşündüğünden daha küçüktür, ancak derleme zamanı olanlara ek olarak araçların çalışma zamanı denetimleri yapmalarını sağlama avantajına sahiptir.
Bir başka önemli fark, kodda ek açıklamaların nerede kullanılabileceğidir. İki farklı yaklaşım vardır. Bazı paketler JLS 9.6.4.1 stil bağlamlarını kullanır. Aşağıdaki tabloda genel bir bakış sunulmaktadır:
SAHA YÖNTEMİ PARAMETRESİ LOCAL_VARIABLE
android.support.annotation XXX
edu.umd.cs.findbugs.annotations XXXX
org.jetbrains.analımı XXXX
lombok XXXX
javax.validation.constraints XXX
org.eclipse.jdt.annotation, javax.annotationVe org.checkerframework.checker.nullness.qualbunu yapmak için doğru yolu Bence olduğunu JLS 4.11, tanımlanan bağlamları kullanın.
Bu bizi
javax.annotation
org.checkerframework.checker.nullness.qual
bu turda.
kod
Daha fazla ayrıntıyı kendiniz karşılaştırmanıza yardımcı olmak için aşağıdaki her ek açıklamanın kodunu listeliyorum. Karşılaştırmayı kolaylaştırmak için yorumları, içe aktarmaları ve @Documentedek açıklamaları kaldırdım . ( @DocumentedAndroid paketindeki sınıflar dışında hepsi vardı ). Çizgileri ve @Targetalanları yeniden sıraladım ve nitelikleri normalleştirdim.
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 {}
Tamlık için, @Nullableuygulamalar şunlardır :
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 {}
Aşağıdaki iki paket yok @Nullable, bu yüzden onları ayrı ayrı listeliyorum; Lombok oldukça sıkıcı @NonNull. Gelen aslında bir olduğunu
ve uzunca bir uygulama vardır.javax.validation.constraints@NonNull@NotNull
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();
}
}
Destek
Deneyimlerime göre javax.annotation, en azından Eclipse ve Checker Framework tarafından kutunun dışında destekleniyor.
özet
İdeal ek açıklamam java.annotationChecker Framework uygulaması ile sözdizimi olacaktır .
Checker Çerçevesini kullanmak istemiyorsanız javax.annotation( JSR-305 ) şu an için en iyi bahistir.
Checker Çerçevesi satın almak istiyorsanız sadece kullanın org.checkerframework.checker.nullness.qual.
Kaynaklar
android.support.annotation itibaren android-5.1.1_r1.jar
edu.umd.cs.findbugs.annotations itibaren findbugs-annotations-1.0.0.jar
org.eclipse.jdt.annotation itibaren org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
org.jetbrains.annotations itibaren jetbrains-annotations-13.0.jar
javax.annotation itibaren gwt-dev-2.5.1-sources.jar
org.checkerframework.checker.nullness.qual itibaren checker-framework-2.1.9.zip
lombokdan lomboktaahhütf6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
javax.validation.constraints itibaren validation-api-1.0.0.GA-sources.jar