चूंकि 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.qual
JLS 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