चूंकि JSR 305 (जिसका लक्ष्य मानकीकृत करना था ) @NonNullऔर @Nullableकई वर्षों से निष्क्रिय है, मुझे डर है कि कोई अच्छा जवाब नहीं है। हम सब एक व्यावहारिक समाधान खोजने के लिए कर सकते हैं और मेरा निम्नानुसार है:
वाक्य - विन्यास
विशुद्ध रूप से शैलीगत दृष्टिकोण से मैं केवल जावा को छोड़कर आईडीई, रूपरेखा या किसी टूलकिट के किसी भी संदर्भ से बचना चाहूंगा।
यह नियम:
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
org.checkerframework.checker.nullness.qual
lombok.NonNull
जो हमें javax.validation.constraintsया तो साथ छोड़ देता है javax.annotation। पूर्व जेईई के साथ आता है। यदि यह इससे बेहतर है javax.annotation, जो अंततः JSE के साथ आ सकता है या कभी नहीं, तो बहस का विषय है। मैं व्यक्तिगत रूप से पसंद करता javax.annotationहूं क्योंकि मुझे जेईई निर्भरता पसंद नहीं है।
यह हमें छोड़ देता है
javax.annotation
जो सबसे छोटा है।
केवल एक सिंटैक्स है जो और भी बेहतर होगा java.annotation.Nullable:। जैसा कि अन्य पैकेजों ने अतीत में स्नातक किया javaxहै java, javax.annotation सही दिशा में एक कदम होगा।
कार्यान्वयन
मैं उम्मीद कर रहा था कि वे सभी मूल रूप से एक ही तुच्छ कार्यान्वयन हैं, लेकिन एक विस्तृत विश्लेषण से पता चला है कि यह सच नहीं है।
समानता के लिए सबसे पहले:
सभी @NonNullएनोटेशन में लाइन है
public @interface NonNull {}
के अलावा
org.jetbrains.annotationsजो इसे कहता है @NotNullऔर इसका एक तुच्छ कार्यान्वयन है
javax.annotation जिसका लंबा कार्यान्वयन है
javax.validation.constraintsजो इसे कॉल भी करता है @NotNullऔर इसका कार्यान्वयन भी होता है
सभी @Nullableएनोटेशन में लाइन है
public @interface Nullable {}
org.jetbrains.annotationsउनके तुच्छ कार्यान्वयन के साथ (फिर से) को छोड़कर ।
अंतर के लिए:
एक हड़ताली एक वह है
javax.annotation
javax.validation.constraints
org.checkerframework.checker.nullness.qual
सभी का रनटाइम एनोटेशन ( @Retention(RUNTIME)) है, जबकि
android.support.annotation
edu.umd.cs.findbugs.annotations
org.eclipse.jdt.annotation
org.jetbrains.annotations
केवल संकलन समय ( @Retention(CLASS)) हैं।
जैसा कि इस एसओ में वर्णित है , रनटाइम एनोटेशन का प्रभाव किसी के विचार से छोटा है, लेकिन उन्हें संकलन समय के अलावा रनटाइम चेक करने के लिए उपकरणों को सक्षम करने का लाभ है।
एक और महत्वपूर्ण अंतर है जहां कोड में व्याख्या का इस्तेमाल किया जा सकता। दो अलग-अलग दृष्टिकोण हैं। कुछ संकुल JLS 9.6.4.1 शैली संदर्भों का उपयोग करते हैं। निम्न तालिका अवलोकन देती है:
FIELD METHOD PARAMETER LOCAL_VARIABLE
android.support.annotation XXX
edu.umd.cs.findbugs.annotations XXXX
org.jetbrains.annotation XXXX
lombok XXXX
javax.validation.constraints XXX
org.eclipse.jdt.annotation, javax.annotationऔर org.checkerframework.checker.nullness.qualJLS 4.11 में परिभाषित संदर्भों का उपयोग करें, जो कि मेरी राय में इसे करने का सही तरीका है।
यह हमें छोड़ देता है
javax.annotation
org.checkerframework.checker.nullness.qual
इस दौर में
कोड
आगे के विवरणों की तुलना करने में आपकी मदद करने के लिए मैं नीचे दिए गए प्रत्येक एनोटेशन के कोड को सूचीबद्ध करता हूं। तुलना को आसान बनाने के लिए मैंने टिप्पणियों, आयातों और @Documentedएनोटेशन को हटा दिया । (वे सभी @Documentedएंड्रॉइड पैकेज से कक्षाओं को छोड़कर) थे। मैंने लाइनों और @Targetक्षेत्रों को फिर से व्यवस्थित किया और योग्यता को सामान्य किया।
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 {}
पूर्णता के लिए, यहाँ @Nullableकार्यान्वयन हैं:
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 {}
निम्नलिखित दो पैकेजों में कोई नहीं है @Nullable, इसलिए मैं उन्हें अलग से सूचीबद्ध करता हूं; लोम्बोक में एक बहुत उबाऊ है @NonNull। में वास्तव में एक है
और यह एक दीर्घाकार कार्यान्वयन है।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();
}
}
सहयोग
मेरे अनुभव से, javax.annotationकम से कम एक्लिप्स और बॉक्स के बाहर चेकर फ्रेमवर्क द्वारा समर्थित है।
सारांश
मेरा आदर्श एनोटेशन java.annotationचेकर फ्रेमवर्क कार्यान्वयन के साथ वाक्यविन्यास होगा ।
यदि आप चेकर फ्रेमवर्क का उपयोग करने का इरादा नहीं रखते हैं javax.annotation( JSR-305 ) अभी भी समय के लिए आपका सबसे अच्छा दांव है।
यदि आप चेकर फ्रेमवर्क में खरीदने के इच्छुक हैं तो बस उनका उपयोग करें org.checkerframework.checker.nullness.qual।
सूत्रों का कहना है
android.support.annotation से android-5.1.1_r1.jar
edu.umd.cs.findbugs.annotations से findbugs-annotations-1.0.0.jar
org.eclipse.jdt.annotation से org.eclipse.jdt.annotation_2.1.0.v20160418-1457.jar
org.jetbrains.annotations से jetbrains-annotations-13.0.jar
javax.annotation से gwt-dev-2.5.1-sources.jar
org.checkerframework.checker.nullness.qual से checker-framework-2.1.9.zip
lombokसे lombokप्रतिबद्धf6da35e4c4f3305ecd1b415e2ab1b9ef8a9120b4
javax.validation.constraints से validation-api-1.0.0.GA-sources.jar