Yana JSR 305 (kimin gol standardize edilerek @NonNull
ve @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.constraints
ya javax.annotation
. Birincisi JEE ile birlikte gelir. Bu, javax.annotation
nihayetinde 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 javax
hiç java
geç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:
@NonNull
Ek açıklamalar, tüm çizgi var
public @interface NonNull {}
dışında
org.jetbrains.annotations
ki bu onu çağırıyor @NotNull
ve önemsiz bir uygulaması var
javax.annotation
daha uzun bir uygulaması olan
javax.validation.constraints
bu da onu çağırır @NotNull
ve bir uygulaması vardır
@Nullable
Ek 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.annotation
Ve org.checkerframework.checker.nullness.qual
bunu 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 @Documented
ek açıklamaları kaldırdım . ( @Documented
Android paketindeki sınıflar dışında hepsi vardı ). Çizgileri ve @Target
alanları 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, @Nullable
uygulamalar ş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.annotation
Checker 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
lombok
dan lombok
taahhütf6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
javax.validation.constraints
itibaren validation-api-1.0.0.GA-sources.jar