कौन सा @NotNull जावा एनोटेशन का उपयोग करना चाहिए?


997

मैं अपने कोड को अधिक पठनीय बनाने के साथ-साथ NullPointerException से बचने के लिए IDE कोड निरीक्षण और / या स्थिर कोड विश्लेषण (FindBugs और Sonar) जैसे टूलिंग का उपयोग करना चाहता हूं। कई उपकरण एक-दूसरे के @NotNull/ @NonNull/ @Nonnullएनोटेशन के साथ असंगत लगते हैं और मेरे कोड में उन सभी को सूचीबद्ध करना पढ़ने के लिए भयानक होगा। कोई भी सुझाव, जिसमें से एक 'सर्वश्रेष्ठ' है? यहाँ मेरे द्वारा किए गए समकक्ष एनोटेशन की सूची दी गई है:

  • javax.validation.constraints.NotNull
    स्थैतिक विश्लेषण के लिए बनाया गया, स्थैतिक विश्लेषण नहीं।
    प्रलेखन

  • edu.umd.cs.findbugs.annotations.NonNull
    द्वारा प्रयुक्त FindBugs स्थिर विश्लेषण और इसलिए सोनार (अब Sonarqube )
    प्रलेखन

  • javax.annotation.Nonnull
    यह फाइंडबग्स के साथ भी काम कर सकता है, लेकिन JSR-305 निष्क्रिय है। (यह भी देखें: JSR 305 की स्थिति क्या है? ) स्रोत

  • org.jetbrains.annotations.NotNull
    स्थैतिक विश्लेषण के लिए IntelliJ IDEA IDE द्वारा उपयोग किया जाता है।
    प्रलेखन

  • lombok.NonNull
    प्रोजेक्ट लोम्बोक में कोड पीढ़ी को नियंत्रित करने के लिए उपयोग किया जाता है ।
    कोई मानक नहीं होने से प्लेसहोल्डर एनोटेशन।
    स्रोत , प्रलेखन

  • android.support.annotation.NonNull
    एंड्रॉइड में उपलब्ध मार्कर एनोटेशन, समर्थन-एनोटेशन पैकेज प्रलेखन द्वारा प्रदान किया गया है

  • org.eclipse.jdt.annotation.NonNull
    स्थिर कोड विश्लेषण प्रलेखन के लिए ग्रहण द्वारा उपयोग किया जाता है


203
अपाचे को "सामान्य" एनोटेशन और एक उपकरण का आविष्कार करना चाहिए जो इसे किसी अन्य एनोटेशन में बदल सकता है। कई मानकों की समस्या का समाधान एक नए मानक का आविष्कार करना है।
0

6
@irreputable अगर अपाचे एक नए "आम" का आविष्कार करता है, तो इसके 56 संस्करण होंगे, अन्य परियोजनाओं के साथ अतिव्यापी। और, यह वैसे भी मानक नहीं होगा (मानक! = व्यापक)। कुछ भी वास्तव में मानक, javax? * का बेहतर उपयोग करें। BTW, उन उदाहरणों में "बहुत अधिक मानक" नहीं हैं, मैं सिर्फ 1 या 2 देखता हूं
ymajoros

6
javax.annotation.Nonnull Findbugs (बस इसे परीक्षण किया गया) के साथ काम करता है, जो मेरे लिए इसका उपयोग करने के लिए एक सम्मोहक कारण है।
निकोलस C

20
अगर मैं केवल @NotNull लिखता हूं, तो यह संदर्भित करता है com.sun.istack.internal.NotNull। OMG ...
थॉमस वेलर

3
@MozartBrocchini - वैकल्पिक उन मामलों में उपयोगी होते हैं जहां आपने पहले NullObjects का उपयोग किया होगा। वे वास्तव में एक रनटाइम के रूप में एक ही उद्देश्य को संबोधित नहीं करते हैं, लेकिन @NotNull एनोटेशन हालांकि, और वे थकाऊ अलौकिक परिचय।
डेव

जवाबों:


205

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

7
नकारात्मक पक्ष javax.annotationयह है कि यह एक) मृत जेएसआर पर आधारित है, बी) एक विरूपण साक्ष्य खोजने के लिए मुश्किल है जो सिर्फ एनोटेशन प्रदान करता है और बनाए रखा जाता है। : FindBugs से एक नहीं है search.maven.org/...
robinst

18
इसके खिलाफ एक और बिंदु javax.annotationयह है कि यह जावा 9 के साथ समस्याओं का कारण बनता है क्योंकि अन्य मॉड्यूल उस पैकेज (jax-ws) में भी कक्षाएं प्रदान करते हैं।
रॉबिन

10
@kevinarpe: फाइंडबग्स प्रोजेक्ट मर चुका है, और उत्तराधिकारी प्रोजेक्ट स्पॉटबग्स उन एनोटेशनों को हटा रहा है: github.com/spotbugs/spotbugs/pull/180
रॉबिन

4
JSR 305 , जो मानकीकृत होता javax.annotation.NonNull, कभी पूरा नहीं हुआ क्योंकि इसकी स्पेक लीड AWOL थी। इसका ओरेकल के किसी भी फैसले से कोई लेना-देना नहीं था।
मार्क रीनहोल्ड

5
Jsr305.jar का उपयोग नहीं करने का एक और कारण यह है कि यह जाहिरा तौर पर ओरेकल जावा बाइनरी लाइसेंस का उल्लंघन करता है: github.com/google/guava/issues/2960
प्रवाह

91

मुझे चेकर फ्रेमवर्क बहुत पसंद है , जो कि टाइप एनोटेशन ( JSR-308 ) का कार्यान्वयन है, जिसका उपयोग अशक्त चेकर की तरह दोष चेकर्स को लागू करने के लिए किया जाता है। मैंने वास्तव में किसी अन्य को किसी भी तुलना की पेशकश करने की कोशिश नहीं की है, लेकिन मैं इस कार्यान्वयन से खुश हूं।

मैं उस समूह से संबद्ध नहीं हूं जो सॉफ़्टवेयर प्रदान करता है, लेकिन मैं एक प्रशंसक हूं।

इस प्रणाली के बारे में चार बातें मुझे पसंद हैं:

  1. इसमें अशक्तता (@ अशक्त) के लिए एक दोष चेकर्स हैं , लेकिन अपरिवर्तनीयता और इंटर्निंग (और अन्य) के लिए भी हैं। मैं पहले एक (अशक्तता) का उपयोग करता हूं और मैं दूसरे (अपरिवर्तनीयता / IGJ) का उपयोग करने की कोशिश कर रहा हूं। मैं तीसरा प्रयास कर रहा हूं, लेकिन मैं अभी तक इसका उपयोग करने के बारे में निश्चित नहीं हूं। मैं अभी तक अन्य चेकर्स की सामान्य उपयोगिता के बारे में आश्वस्त नहीं हूं, लेकिन यह जानकर अच्छा लगा कि फ्रेमवर्क विभिन्न अतिरिक्त एनोटेशन और चेकर्स को लागू करने के लिए एक प्रणाली है।

  2. Nullness जाँच के लिए डिफ़ॉल्ट सेटिंग स्थानीय लोगों (nnel) को छोड़कर गैर अशक्त: अच्छी तरह से काम करता है। मूल रूप से इसका मतलब यह है कि डिफ़ॉल्ट रूप से चेकर स्थानीय चर को छोड़कर हर (उदाहरण चर, विधि पैरामीटर, सामान्य प्रकार, आदि) व्यवहार करता है जैसे कि उनके पास डिफ़ॉल्ट रूप से एक @ नया प्रकार है। प्रलेखन के अनुसार:

    NNEL डिफ़ॉल्ट आपके कोड में सबसे छोटी संख्या में स्पष्ट एनोटेशन की ओर जाता है।

    यदि आप NNEL आपके लिए काम नहीं करते हैं तो आप किसी वर्ग के लिए या किसी विधि के लिए एक अलग डिफ़ॉल्ट सेट कर सकते हैं।

  3. यह ढांचा आपको टिप्पणी में अपने एनोटेशन को संलग्न करके फ्रेमवर्क पर निर्भरता बनाए बिना उपयोग करने की अनुमति देता है : जैसे /*@Nullable*/। यह अच्छा है क्योंकि आप किसी लाइब्रेरी या शेयर्ड कोड को एनोटेट और चेक कर सकते हैं, लेकिन फिर भी किसी अन्य प्रोजेक्ट में उस लाइब्रेरी / शेयर्ड कोडेड का उपयोग करने में सक्षम होंगे जो फ्रेमवर्क का उपयोग नहीं करते हैं। यह एक अच्छी सुविधा है। मैं इसका उपयोग करने का आदी हो गया हूं, भले ही मैं अब अपने सभी प्रोजेक्टों पर चेकर फ्रेमवर्क को सक्षम करने के लिए तैयार हूं।

  4. फ़्रेमवर्क में आपके द्वारा उपयोग किए जाने वाले APIs को एनोटेट करने का एक तरीका है जो पहले से ही स्टबल फ़ाइलों का उपयोग करके शून्यता के लिए एनोटेट नहीं किया गया है।


3
बहुत अच्छा लगता है और मैं इसका इस्तेमाल करना चाहूंगा, लेकिन नहीं कर सकता। जीपीएल क्यों? क्या इसके बदले LGPL नहीं हो सकता था?
बुर्खर्ड

13
एफएक्यू के अनुसार : "अधिक अनुमेय एमआईटी लाइसेंस कोड पर लागू होता है जिसे आप अपने स्वयं के कार्यक्रम में शामिल कर सकते हैं, जैसे कि एनोटेशन।"
सीन

1
वर्तमान में लिंक टूट गए हैं। लेकिन चेकर फ्रेमवर्क का उपयोग करने की सलाह के लिए +1।
पॉल वैग्लैंड

1
यह अफ़सोस की बात है कि नवीनतम रिलीज़ में अपरिवर्तनीय चेकर्स को छोड़ दिया जाता है।
फ्रैंकलिन यू

1
Oracle जावा ट्यूटोरियल्स में चेकर फ्रेमवर्क का भी सुझाव दिया गया है ।
क़ाज़ी इरफ़ान

55

मैं IntelliJ एक का उपयोग करता हूं, क्योंकि मैं ज्यादातर IntelliJ के साथ संबंध रखता हूं जो एक एनपीई का उत्पादन कर सकते हैं। मैं मानता हूं कि यह JDK में एक मानक एनोटेशन नहीं होने पर निराशा होती है। इसे जोड़ने की बात है, यह इसे जावा 7 में बना सकता है। किस स्थिति में चुनने के लिए एक और होगा!


68
अद्यतन: IntelliJ अब कोड हाइलाइटिंग के लिए उपरोक्त सभी एनोटेशन का समर्थन करता है, इसलिए आप IntelliJ के एनोटेशन पर किसी भी अधिक प्रतिबंध नहीं लगाते हैं: blogs.jetbrains.com/idea/2011/03/…
डैनियल एलेक्सीuc

31
और इसलिए ग्रहण जूनो!
jFrenetic

5
javax.annotation.Nonnullअधिक व्यापक रूप से स्वीकार किया जाता है, है ना?
मार्टिन

1
@DanielAlexiuc लेकिन दुर्भाग्य से, यह उन्हें अपने रनटाइम चेक के लिए उपयोग नहीं करता है, इसलिए अभी भी JetBrains वाले का उपयोग करने के लिए एक लाभ है ...
Trejkaz

4
@Trejkaz 2016.3 के बाद से यह उन सभी के लिए रनटाइम चेक बनाता है।
करोल एस

32

जावा 7 सुविधाओं की सूची के अनुसार JSR-308 प्रकार के एनोटेशन Java 8 में आस्थगित हैं। JSR-305 एनोटेशन का भी उल्लेख नहीं किया गया है।

नवीनतम JSR-308 ड्राफ्ट के परिशिष्ट में JSR-305 की स्थिति पर थोड़ी जानकारी है । इसमें वह अवलोकन शामिल है जिसे JSR-305 एनोटेशन को छोड़ दिया गया लगता है। JSR-305 पृष्ठ इसे "निष्क्रिय" के रूप में भी दिखाता है।

इस बीच में, व्यावहारिक जवाब एनोटेशन प्रकारों का उपयोग करना है जो कि सबसे व्यापक रूप से उपयोग किए जाने वाले उपकरणों द्वारा समर्थित हैं ... और अगर स्थिति बदलती है तो उन्हें बदलने के लिए तैयार रहें।


वास्तव में, JSR-308 किसी भी एनोटेशन प्रकार / वर्गों को परिभाषित नहीं करता है, और ऐसा लगता है कि वे सोचते हैं कि यह दायरे से बाहर है। (और वे सही हैं, जेएसआर-305 के अस्तित्व को देखते हुए)।

हालाँकि, अगर JSR-308 वास्तव में इसे Java 8 में बनाने जैसा लगता है, तो मुझे यह आश्चर्य नहीं होगा कि JSR-305 में रुचि फिर से बढ़ी। AFAIK, JSR-305 टीम ने औपचारिक रूप से अपना काम नहीं छोड़ा है। वे सिर्फ 2+ साल से शांत हैं।

यह दिलचस्प है कि बिल पुघ (JSR-305 के लिए तकनीकी नेतृत्व) फाइंडबग्स के पीछे एक आदमी है।


4
@pst - वर्तमान शेड्यूल जावा 8 के लिए सितंबर 2013 में सामान्य रिलीज पर जाने के लिए है - infoq.com/news/2012/04/jdk-8-milestone-release-dates
स्टीफन सी

2
यह अब मार्च 2014 तक खिसक गया है - openjdk.java.net/projects/jdk8 । JSR 308, M7 ("104 प्रकार पर व्याख्या" में देखें) के निर्माण में शामिल है।
स्टीफन सी

28

एंड्रॉयड परियोजनाओं के लिए आप का उपयोग करना चाहिए android.support.annotation.NonNullऔर android.support.annotation.Nullable। ये और अन्य सहायक Android- विशिष्ट एनोटेशन समर्थन लाइब्रेरी में उपलब्ध हैं ।

से http://tools.android.com/tech-docs/support-annotations :

इन एनोटेशन के साथ ही सपोर्ट लाइब्रेरी को भी एनोटेट किया गया है, इसलिए सपोर्ट लाइब्रेरी के उपयोगकर्ता के रूप में, एंड्रॉइड स्टूडियो पहले से ही इन एनोटेशन के आधार पर आपके कोड और फ्लैग संभावित समस्याओं की जांच करेगा।


3
उस सिफारिश का औचित्य प्रदान करना उपयोगी होगा।
खुबानी

2
tools.android.com/tech-docs/support-annotations "समर्थन पुस्तकालय में भी इन एनोटेशन के साथ एनोटेट किया गया है, इसलिए समर्थन लाइब्रेरी के उपयोगकर्ता के रूप में, एंड्रॉइड स्टूडियो पहले से ही इन एनोटेशन के आधार पर आपके कोड और फ्लैग संभावित समस्याओं की जांच करेगा। । "
जेम्स वॉल्ड

3
BTW Android स्टूडियो javax.annotation.*एनोटेशन के साथ jsr305 का भी समर्थन करता है
CAMOBAP

19

अगर किसी को सिर्फ इंटेलीज क्लासेस की तलाश है: आप उन्हें मावेन रिपॉजिटरी से प्राप्त कर सकते हैं

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations</artifactId>
    <version>15.0</version>
</dependency> 

यह वही है जो इंटेलीज को चेतावनी को फेंकने का कारण बनता है, हां।
अपवोट

वर्तमान संस्करण (05/2017 तक) 15.0
BamaPookie

आपका अधिकार। मैंने संस्करण अद्यतन किया है। अगर मुझे लगता है कि यह ज्यादा नहीं बदला है।
ब्रूनो एबरहार्ड

ध्यान रखें कि JetBrains एनोटेशन को रनटाइम के लिए बरकरार नहीं रखा जाता है, इसलिए उदाहरण के लिए Guice @Nullable समर्थन इसके साथ काम नहीं करता है।
पीटर मेजर

18

JSR305 और फाइंडबग्स को एक ही व्यक्ति द्वारा लिखा गया है। दोनों खराब तरीके से बनाए हुए हैं, लेकिन मानक के रूप में यह हो जाता है और सभी प्रमुख आईडीई द्वारा समर्थित हैं। अच्छी खबर यह है कि वे अच्छी तरह से काम करते हैं।

यहां बताया गया है कि डिफ़ॉल्ट रूप से सभी वर्गों, विधियों और क्षेत्रों में @Nonnull कैसे लागू करें। देखें https://stackoverflow.com/a/13319541/14731 और https://stackoverflow.com/a/9256595/14731

  1. परिभाषित करें @NotNullByDefault
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;


    /**
     * This annotation can be applied to a package, class or method to indicate that the class fields,
     * method return types and parameters in that element are not null by default unless there is: <ul>
     * <li>An explicit nullness annotation <li>The method overrides a method in a superclass (in which
     * case the annotation of the corresponding parameter in the superclass applies) <li> there is a
     * default parameter annotation applied to a more tightly nested element. </ul>
     * <p/>
     * @see https://stackoverflow.com/a/9256595/14731
     */
    @Documented
    @Nonnull
    @TypeQualifierDefault(
    {
        ElementType.ANNOTATION_TYPE,
        ElementType.CONSTRUCTOR,
        ElementType.FIELD,
        ElementType.LOCAL_VARIABLE,
        ElementType.METHOD,
        ElementType.PACKAGE,
        ElementType.PARAMETER,
        ElementType.TYPE
    })
    @Retention(RetentionPolicy.RUNTIME)
    public @interface NotNullByDefault
    {
    }

2. प्रत्येक पैकेज में एनोटेशन जोड़ें: package-info.java

@NotNullByDefault
package com.example.foo;

अद्यतन : 12 दिसंबर, 2012 तक जेएसआर 305 को "निष्क्रिय" के रूप में सूचीबद्ध किया गया है। प्रलेखन के अनुसार:

एक जेएसआर जिसे कार्यकारी समिति द्वारा "निष्क्रिय" के रूप में वोट दिया गया था, या एक जो अपने प्राकृतिक जीवनकाल के अंत तक पहुंच गया है।

ऐसा लगता है कि JSR 308 है JDK 8 में यह कर रही है और हालांकि JSR @NotNull परिभाषित नहीं करता है, के साथ Checkers Frameworkकरता है। इस लेखन के समय, मेव प्लगइन इस बग के कारण अनुपयोगी है: https://github.com/typetools/checker-framework/issues/183


2
मावेन के लिए शोस्टॉपर मुद्दा तय हो गया है। तो यह फिर से एक विकल्प होना चाहिए।
मार्क वॉन रेंटेलन

मैं मावेन के माध्यम से फाइंडबग्स का उपयोग करता हूं, मेरी आईडीई द्वारा कुछ भी नहीं किया जाता है, यह आईडीई विशिष्ट एनोटेशन से बचा जाता है, आप क्या सलाह देंगे?
क्रिस्टोफ रूसो

@ChristopheRoussy आपका प्रश्न IDE- विशिष्ट है। कृपया एक अलग प्रश्न खोलें।
गिली

15

स्थैतिक विश्लेषण और रनटाइम विश्लेषण के बीच भेद। आंतरिक सामान के लिए स्थैतिक विश्लेषण का उपयोग करें, और अपने कोड की सार्वजनिक सीमाओं के लिए रनटाइम विश्लेषण।

उन चीजों के लिए जो शून्य नहीं होनी चाहिए:

  • रनटाइम चेक: "if (x == null) ..." (शून्य निर्भरता) या @ javax.validation.NotNull (सेम सत्यापन के साथ) या @ lombok.NonNull (सादा और सरल या guavas Preconditions.checkNotNull (..) का उपयोग करें। ।)

    • विधि वापसी प्रकार (केवल) के लिए वैकल्पिक का उपयोग करें। या तो जावा 8 या अमरूद।
  • स्टेटिक चेक: एक @NonNull एनोटेशन का उपयोग करें

  • जहां यह फिट बैठता है, वर्ग या पैकेज स्तर पर @ ... NonnullByDefault एनोटेशन का उपयोग करें। इन एनोटेशन को स्वयं बनाएं (उदाहरण खोजना आसान है)।
    • और, NPEs से बचने के लिए विधि रिटर्न पर @ ... CheckForNull का उपयोग करें

यह सबसे अच्छा परिणाम देना चाहिए: IDE में चेतावनी, फाइंडबग्स और चेकरफ्रैमवर्क द्वारा त्रुटियां, सार्थक रनटाइम अपवाद।

स्थिर चेक के परिपक्व होने की उम्मीद न करें, उनका नामकरण मानकीकृत नहीं है और विभिन्न पुस्तकालय और आईडीई उन्हें अलग तरह से व्यवहार करते हैं, उन्हें अनदेखा करते हैं। JSR305 javax.annotations। * कक्षाएं मानक की तरह दिखती हैं, लेकिन वे नहीं हैं, और वे Java9 + के साथ विभाजित पैकेज का कारण बनती हैं।

कुछ नोट्स स्पष्टीकरण:

  • पैकेज javax.validation के साथ फाइंडबग्स / स्पॉटबग्स / jsr305 एनोटेशन। जावा 9 + में अन्य मॉड्यूल के साथ टकराव, संभवतः ओरेकल लाइसेंस का भी उल्लंघन करते हैं।
  • स्पॉटबग्स एनोटेशन अभी भी jsr305 / findbugs एनोटेशन कंपाइलटाइम पर ( https://github.com/spotbugs/spotbugs/issues/421 लिखने के समय ) पर निर्भर करता है
  • jetbrains @NotNull नाम का @ javax.validation.NotNull के साथ टकराव हुआ।
  • स्थैतिक जाँच के लिए जेटब्रेन्स, एक्लिप्स या चेकर्सफ्रेमवर्क एनोटेशन से javax.annotations पर लाभ होता है कि वे Java9 और उच्चतर में अन्य मॉड्यूल के साथ नहीं टकराते हैं
  • @ javax.annotations.ullable Findbugs / Spotbugs का मतलब यह नहीं है कि आप (या आपकी IDE) को इसका क्या मतलब है। फाइंडबग्स इसे (सदस्यों पर) नजरअंदाज करेंगे। दु: खद, लेकिन सच ( https://sourceforge.net/p/findbugs/bugs/1181 )
  • IDE के बाहर स्थिर जाँच के लिए, 2 निःशुल्क टूल मौजूद हैं: स्पॉटबग्स (पूर्व में फाइंडबग्स) और चेकर्सफ्रेमवर्क।
  • Eclipse लाइब्रेरी में @NonNullByDefault, jsr305 में केवल @ParametersAreNonnullByDefault है। वे एक पैकेज (या वर्ग) में सब कुछ के लिए आधार एनोटेशन को लागू करने वाले सुविधा आवरण हैं, आप आसानी से अपना खुद का बना सकते हैं। यह पैकेज पर इस्तेमाल किया जा सकता है। यह उत्पन्न कोड (जैसे lombok) के साथ संघर्ष हो सकता है।
  • निर्यात पर निर्भरता के रूप में लुम्बोक का उपयोग करने से उन पुस्तकालयों के लिए बचा जाना चाहिए जिन्हें आप अन्य लोगों के साथ साझा करते हैं, कम सकरात्मक निर्भरता, बेहतर
  • बीन सत्यापन फ्रेमवर्क का उपयोग करना शक्तिशाली है, लेकिन इसके लिए उच्च ओवरहेड की आवश्यकता होती है, इसलिए यह मैनुअल नल जाँच से बचने के लिए ओवरकिल है।
  • फ़ील्ड और विधि मापदंडों के लिए वैकल्पिक का उपयोग करना विवादास्पद है (आप आसानी से इसके बारे में लेख पा सकते हैं)
  • एंड्रॉइड नल एनोटेशन एंड्रॉइड सपोर्ट लाइब्रेरी का हिस्सा हैं, वे कई अन्य वर्गों के साथ आते हैं, और अन्य एनोटेशन / टूल के साथ अच्छी तरह से नहीं खेलते हैं।

Java9 से पहले, यह मेरी सिफारिश है:

// file: package-info.java
@javax.annotation.ParametersAreNonnullByDefault
package example;


// file: PublicApi
package example;

public interface PublicApi {

    Person createPerson(
        // NonNull by default due to package-info.java above
        String firstname,
        String lastname);
}

// file: PublicApiImpl
public class PublicApiImpl implements PublicApi {
    public Person createPerson(
            // In Impl, handle cases where library users still pass null
            @Nullable String firstname, // Users  might send null
            @Nullable String lastname // Users might send null
            ) {
        if (firstname == null) throw new IllagalArgumentException(...);
        if (lastname == null) throw new IllagalArgumentException(...);
        return doCreatePerson(fistname, lastname, nickname);
    }

    @NonNull // Spotbugs checks that method cannot return null
    private Person doCreatePerson(
             String firstname, // Spotbugs checks null cannot be passed, because package has ParametersAreNonnullByDefault
             String lastname,
             @Nullable String nickname // tell Spotbugs null is ok
             ) {
         return new Person(firstname, lastname, nickname);
    }

    @CheckForNull // Do not use @Nullable here, Spotbugs will ignore it, though IDEs respect it
    private Person getNickname(
         String firstname,
         String lastname) {
         return NICKNAMES.get(firstname + ':' + lastname);
    }
}

ध्यान दें कि स्पॉटबग्स बनाने के लिए कोई तरीका नहीं है जब एक अशक्त विधि पैरामीटर को डीरएफ़ेड किया जाता है (लेखन के समय, स्पॉटबग्स के संस्करण 3.1)। शायद चेकरफ्रेमवर्क ऐसा कर सकता है।

अफसोस की बात है कि ये एनोटेशन किसी पुस्तकालय की सार्वजनिक पद्धति के मामलों के बीच मनमाने ढंग से कॉल करने और गैर-सार्वजनिक तरीकों के बीच अंतर नहीं करते हैं, जहां प्रत्येक कॉलसाइट को जाना जा सकता है। तो इसका दोहरा अर्थ है: "इंगित करें कि अशक्त अवांछित है, लेकिन फिर भी अशक्त पारित होने के लिए तैयार करें" एक भी घोषणा में संभव नहीं है, इसलिए उपरोक्त उदाहरण में इंटरफ़ेस और कार्यान्वयन के लिए अलग-अलग एनोटेशन हैं।

उन मामलों के लिए जहां विभाजन इंटरफ़ेस दृष्टिकोण व्यावहारिक नहीं है, निम्नलिखित दृष्टिकोण एक समझौता है:

        public Person createPerson(
                @NonNull String firstname,
                @NonNull String lastname
                ) {
            // even though parameters annotated as NonNull, library clients might call with null.
            if (firstname == null) throw new IllagalArgumentException(...);
            if (lastname == null) throw new IllagalArgumentException(...);
            return doCreatePerson(fistname, lastname, nickname);
        }

यह ग्राहकों को अशक्त (सही कोड लिखने) को पारित नहीं करने में मदद करता है, जबकि यदि वे करते हैं तो उपयोगी त्रुटियां लौटाते हैं।


मुझे यह उत्तर अभी मिला है, लेकिन @tkruse, आपको यह कहां से मिला: "ग्रहण jdt एनोटेशन स्थैतिक विधि रिटर्न और कुछ अन्य मामलों पर लागू नहीं होते हैं"? (पहला भाग सत्य नहीं है, दूसरा काफी अस्पष्ट :))।
स्टीफन हेरमैन 18

@StephanHerrmann: मुझे याद नहीं है। मैंने बुलेट पॉइंट हटा दिया।
1

12

ग्रहण की भी अपनी व्याख्याएँ हैं।

org.eclipse.jdt.annotation.NonNull

पर देखें http://wiki.eclipse.org/JDT_Core/Null_Analysis जानकारी के लिए।


ऐसा लग रहा है कि यह ग्रहण 3.8 (जूनो) से एकीकृत होने जा रहा है जो इस संबंध में इंटेलीज के साथ ग्रहण को इन-लाइन लाएगा। इसके अलावा यह आपको अपने स्वयं के अशक्त एनोटेशन (जैसे javax.annotation.Nonnull) को कॉन्फ़िगर करने की अनुमति देनी चाहिए और नोटनल को डिफ़ॉल्ट होने का विकल्प है।
मोति स्ट्रोम

11

केवल यह बताते हुए कि जावा सत्यापन एपीआई ( javax.validation.constraints.*) @Nullableएनोटेशन के साथ नहीं आता है , जो स्थैतिक विश्लेषण के संदर्भ में बहुत मूल्यवान है। यह रनटाइम बीन सत्यापन के लिए समझ में आता है क्योंकि यह जावा में किसी भी गैर-आदिम क्षेत्र के लिए डिफ़ॉल्ट है (यानी मान्य / लागू करने के लिए कुछ भी नहीं)। प्रयोजनों के लिए कहा गया है कि विकल्पों की ओर तौलना चाहिए।


7

दुर्भाग्य से, JSR 308इस परियोजना से अधिक मूल्यों को नहीं जोड़ा जाएगा स्थानीय नॉट नल का सुझाव यहां

Java 8एकल डिफ़ॉल्ट एनोटेशन या अपने स्वयं के Checkerढांचे के साथ नहीं आएगा । फाइंड-बग्स के समान या JSR 305, यह JSR ज्यादातर शैक्षणिक टीमों के एक छोटे समूह द्वारा खराब बनाए रखा जाता है।

इसके पीछे कोई व्यावसायिक शक्ति नहीं है, इस प्रकार अब (अर्ली ड्राफ्ट की समीक्षा ) JSR 308लॉन्च होती है , जबकि इसे 6 महीने से कम समय में शिप करना चाहिए: -O btw के समान । लेकिन इसके विपरीत अब इसके संस्थापकों से कार्यभार ले लिया गया है ताकि वे जावा प्लेटफॉर्म को नुकसान पहुंचा सकें।EDR 3JCPJava 8310308 Oracle

हर प्रोजेक्ट, वेंडर और अकादमिक वर्ग के पीछे की तरह Checker Frameworkऔर JSR 308अपनी खुद की मालिकाना चेकर एनोटेशन बनाएंगे।

, आने वाले वर्षों के लिए स्रोत कोड असंगत बनाना जब तक कुछ लोकप्रिय समझौता पाया जा सकता है और हो सकता है करने के लिए जोड़ा Java 9या 10, या जैसे चौखटे के माध्यम से Apache Commonsया Google Guava;-)


7

एंड्रॉयड

यह उत्तर Android विशिष्ट है। एंड्रॉइड में सपोर्ट पैकेज कहा जाता है support-annotations। यह प्रदान करता है दर्जनों की एंड्रॉयड विशिष्ट एनोटेशन और भी प्रदान करता है आम लोगों की तरह NonNull, Nullableआदि

जोड़ने के लिए समर्थन-एनोटेशन पैकेज, अपने build.gradle में निम्नलिखित निर्भरता जोड़ें:

compile 'com.android.support:support-annotations:23.1.1'

और फिर उपयोग करें:

import android.support.annotation.NonNull;

void foobar(@NonNull Foo bar) {}

5

इसके लिए अपस्ट्रीम (जावा 8?) को छाँटने की प्रतीक्षा करते हुए, आप केवल अपने स्वयं के प्रोजेक्ट-स्थानीय @NotNullऔर @Nullableएनोटेशन को भी परिभाषित कर सकते हैं । यह उस स्थिति में भी उपयोगी हो सकता है जब आप जावा एसई के साथ काम कर रहे हों, जहां डिफ़ॉल्ट रूप से javax.validation.constraints उपलब्ध नहीं है

import java.lang.annotation.*;

/**
 * Designates that a field, return value, argument, or variable is
 * guaranteed to be non-null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface NotNull {}

/**
 * Designates that a field, return value, argument, or variable may be null.
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.LOCAL_VARIABLE})
@Documented
@Retention(RetentionPolicy.CLASS)
public @interface Nullable {}

यह मोटे तौर पर सजावटी या भविष्य के सबूत के उद्देश्यों के लिए होगा, क्योंकि उपरोक्त स्पष्ट रूप से नहीं है और स्वयं इन एनोटेशन के स्थैतिक विश्लेषण के लिए कोई समर्थन जोड़ते हैं।


4

यदि आप एंड्रॉइड के लिए विकसित कर रहे हैं, तो आप कुछ हद तक ग्रहण (संपादन: लेखन के समय, अब और नहीं) से बंधे हैं , जिसकी अपनी व्याख्या है। यह एक्लिप्स 3.8+ (जूनो) में शामिल है, लेकिन डिफ़ॉल्ट रूप से अक्षम है।

आप इसे वरीयताएँ> जावा> कंपाइलर> त्रुटियों / चेतावनियों> अशक्त विश्लेषण (तल पर संक्षिप्त करने योग्य अनुभाग) में सक्षम कर सकते हैं।

"एनोटेशन-आधारित अशक्त विश्लेषण सक्षम करें" जांचें

http://wiki.eclipse.org/JDT_Core/Null_Analysis#Usage की सेटिंग्स पर सिफारिशें हैं। हालाँकि, यदि आपके पास अपने कार्यक्षेत्र में बाहरी परियोजनाएँ हैं (जैसे facebook SDK), तो वे उन अनुशंसाओं को पूरा नहीं कर सकते हैं, और आप शायद उन्हें प्रत्येक SDK अपडेट के साथ ठीक नहीं करना चाहते; ;-)

मैं उपयोग करता हूं:

  1. नल सूचक पहुंच: त्रुटि
  2. नल विनिर्देशन का उल्लंघन: त्रुटि (बिंदु # 1 से जुड़ी)
  3. संभावित अशक्त सूचक पहुंच: चेतावनी (अन्यथा फेसबुक एसडीके की चेतावनी होगी)
  4. अशक्त एनोटेशन और अशक्त अनुमान के बीच संघर्ष: चेतावनी (बिंदु # 3 से जुड़ा)

4
ग्रहण से बंधा? सच नहीं।
dcow

1
एंड्रॉइड dev`ing के समर्थन के साथ @DavidCowden IntelliJ IDEA, मुझे लगता है, AndroidStudio के पहले कुछ समय पहले उपलब्ध था।
मालती ब्रीडिस

@ Mārti MšBriedis हाँ, यह सच है। मुझे लगता है कि आपका मतलब था @chaqke
dcow

यह ध्यान देने योग्य है कि एंड्रॉइड और इंटेलीज में अलग-अलग एनोटेशन हैं, और संभवतया इस तरह से रहेगा जब तक कि जावा में आधिकारिक एनोटेशन शामिल नहीं हैं। ये ग्रहण के साथ ग्रहण के एनोटेशन का उपयोग करने के निर्देश हैं।
chaqke

यह कभी भी ग्रहण से बंधा नहीं है। आप अपनी इच्छानुसार किसी भी IDE का उपयोग कर सकते हैं।
डेनिसके

4

यदि आप एक बड़ी परियोजना पर काम कर रहे हैं, तो आप अपना @Nullable और / या @NotNullएनोटेशन बनाने के लिए बेहतर हो सकते हैं ।

उदाहरण के लिए:

@java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS)
@java.lang.annotation.Target({java.lang.annotation.ElementType.FIELD,
                              java.lang.annotation.ElementType.METHOD,    
                              java.lang.annotation.ElementType.PARAMETER,
                              java.lang.annotation.ElementType.LOCAL_VARIABLE})
public @interface Nullable 
{
}

यदि आप सही अवधारण नीति का उपयोग करते हैं , तो एनोटेशन रनटाइम पर उपलब्ध नहीं होगा । उस दृष्टिकोण से, यह सिर्फ एक आंतरिक चीज है।

भले ही यह एक सख्त विज्ञान नहीं है, मुझे लगता है कि इसके लिए एक आंतरिक वर्ग का उपयोग करना सबसे अधिक समझ में आता है।

  • यह एक आंतरिक बात है। (कोई कार्यात्मक या तकनीकी प्रभाव नहीं)
  • बहुत से बहुत सारे उपयोगों के साथ।
  • IDE की तरह IntelliJ कस्टम @Nullable/ @NotNullएनोटेशन का समर्थन करता है ।
  • अधिकांश चौखटे अपने स्वयं के आंतरिक संस्करण का भी उपयोग करना पसंद करते हैं।

अतिरिक्त प्रश्न (टिप्पणियाँ देखें):

IntelliJ में इसे कैसे कॉन्फ़िगर करें?

IntelliJ स्थिति पट्टी के निचले दाएं कोने में "पुलिस अधिकारी" पर क्लिक करें। और पॉपअप में "निरीक्षण कॉन्फ़िगर करें" पर क्लिक करें। आगे ... एनोटेशन कॉन्फ़िगर करें


1
मैं आपकी सलाह कोशिश की, लेकिन ideaकुछ भी नहीं बता के बारे में void test(@NonNull String s) {}द्वारा कहा जाता हैtest(null);
user1244932

3
@ user1244932 क्या आपका मतलब है IntelliJ IDEA? आप स्थैतिक विश्लेषण के लिए उपयोग किए जाने वाले अशक्त एनोटेशन को कॉन्फ़िगर कर सकते हैं। मुझे नहीं पता कि कहां, लेकिन उन्हें परिभाषित करने के लिए एक जगह "फ़ाइल> सेटिंग्स> बिल्ड, एक्ज़ीक्यूशन, डिप्लॉयमेंट> कंपाइलर" में है और एक बटन "कॉन्फ़िगर एनोटेशन ..." है।
Adowrath

@ user1244932 स्क्रीनशॉट देखें अगर आप अभी भी इसके लिए देख रहे हैं।
bvdb

3

यहां पहले से ही बहुत सारे उत्तर हैं, लेकिन (ए) यह 2019 है, और अभी भी कोई "मानक" नहीं है Nullableऔर (बी) कोई अन्य उत्तर रेफ़रल नहीं है।

कोटलिन का संदर्भ महत्वपूर्ण है, क्योंकि कोटलिन जावा के साथ 100% इंटरऑपरेबल है और इसमें कोर नल सेफ्टी फीचर है। जावा पुस्तकालयों को कॉल करते समय, यह उन एनोटेशन का लाभ ले सकता है जो कोटलिन टूल को बताएंगे कि क्या जावा एपीआई स्वीकार कर सकता है या वापस लौट सकता है null

जहां तक ​​मुझे पता है, Nullableकोटलिन के साथ संगत एकमात्र पैकेज org.jetbrains.annotationsऔर android.support.annotation(अब androidx.annotation) हैं। उत्तरार्द्ध केवल एंड्रॉइड के साथ संगत है, इसलिए इसका उपयोग गैर-एंड्रॉइड जेवीएम / जावा / कोटलिन परियोजनाओं में नहीं किया जा सकता है। हालाँकि, JetBrains पैकेज हर जगह काम करता है।

इसलिए यदि आप जावा पैकेज विकसित करते हैं जो एंड्रॉइड और कोटलिन में भी काम करना चाहिए (और एंड्रॉइड स्टूडियो और इंटेलीज द्वारा समर्थित है), तो आपकी सबसे अच्छी पसंद शायद जेटब्रेन पैकेज है।

Maven:

<dependency>
    <groupId>org.jetbrains</groupId>
    <artifactId>annotations-java5</artifactId>
    <version>15.0</version>
</dependency>

Gradle:

implementation 'org.jetbrains:annotations-java5:15.0'

2
हम्म, यह अन्यथा कहता है: kotlinlang.org/docs/reference/…
skagedal

3

जावा 8 में ऐसा करने का एक और तरीका है। मैं 2 चीजें कर रहा हूं, जो मुझे चाहिए।

  1. अशक्त क्षेत्रों को लपेटकर अशक्त क्षेत्रों को स्पष्ट प्रकार से बनाना java.util.Optional
  2. जाँच कर रहा है कि निर्माण के समय सभी गैर अशक्त क्षेत्र अशक्त नहीं हैं java.util.Objects.requireNonNull

उदाहरण:

import static java.util.Objects.requireNonNull;

public class Role {

  private final UUID guid;
  private final String domain;
  private final String name;
  private final Optional<String> description;

  public Role(UUID guid, String domain, String name, Optional<String> description) {
    this.guid = requireNonNull(guid);
    this.domain = requireNonNull(domain);
    this.name = requireNonNull(name);
    this.description = requireNonNull(description);
  }

तो मेरा प्रश्न यह है कि क्या हमें java 8 का उपयोग करते समय एनोटेट करने की आवश्यकता है?

संपादित करें: मुझे बाद में पता चला कि कुछ लोग Optionalतर्कों में उपयोग करने के लिए एक बुरे व्यवहार पर विचार करते हैं, यहां पेशेवरों और विपक्षों के साथ एक अच्छी चर्चा है कि जावा 8 के वैकल्पिक का उपयोग तर्कों में क्यों नहीं किया जाना चाहिए

वैकल्पिक विकल्प दिया गया कि यह तर्क में वैकल्पिक का उपयोग करने के लिए अनुशंसित नहीं है, हमें 2 निर्माणकर्ताओं की आवश्यकता है:

  //Non null description
  public Role(UUID guid, String domain, String name, String description) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);

        // description will never be null
        requireNonNull(description);

        // but wrapped with an Optional
        this.description = Optional.of(description);
      }

  // Null description is assigned to Optional.empty
  public Role(UUID guid, String domain, String name) {
        this.guid = requireNonNull(guid);
        this.domain = requireNonNull(domain);
        this.name = requireNonNull(name);
        this.description = Optional.empty();
      }

मैं कहता हूं कि आपको अभी भी सभी 4 औपचारिक मापदंडों के लिए @NotNull एनोटेशन की आवश्यकता है ताकि स्थैतिक विश्लेषण चेकर्स आपके इरादे को जान सकें कि कोई भी अशक्त नहीं होना चाहिए। जावा भाषा में अभी तक कुछ भी नहीं है जो इसे लागू करता है। यदि आप रक्षात्मक रूप से प्रोग्रामिंग कर रहे हैं, तो आपको उस विवरण की भी जाँच करनी चाहिए जो अशक्त नहीं है।
jaxzin

2
मैं अभी भी इस कोड को लिख सकता हूं new Role(null,null,null,null);:। एनोटेशन के साथ मेरी आईडीई और स्थैतिक विश्लेषण चेतावनी देगा कि अशक्त को उन मापदंडों में पारित नहीं किया जा सकता है। इसके बिना मुझे पता नहीं चलता जब तक मैं कोड नहीं चलाता। यह एनोटेशन का मूल्य है।
jaxzin

2
मैं ऐसे वातावरण में भी हूँ जहाँ डेवलपर्स किसी भी IDE या पाठ संपादक का उपयोग कर सकते हैं, जो वे पसंद करते हैं, न कि पारस्परिक रूप से अनन्य। फिर हम मावेन-पीएमडी-प्लगइन और / या सोनारक्यूब को निर्माण प्रक्रिया में प्रोत्साहित करने और उजागर करने के लिए एकीकृत करते हैं, और यहां तक ​​कि गेट, कोड गुणवत्ता के मुद्दों को पूर्व-मर्ज करते हैं, उदाहरण के लिए पुल अनुरोधों पर।
jaxzin

2
वैकल्पिक का मतलब विधि तर्क या निजी क्षेत्र के रूप में उपयोग करने के लिए नहीं है। उदाहरण के लिए देखें: stuartmarks.wordpress.com/2016/09/27/vjug24-session-on-optional
assylias

1
@assylias हाँ, मैंने पाया कि बाद में, वे कहते हैं कि यह अनुशंसित नहीं है क्योंकि यह हमें कुछ भी नहीं खरीदेगा, मैं निश्चित रूप से उनके तर्कसंगत समझ सकता हूं। इस मामले में मैंने यहाँ रखा है, एक तर्क description को शून्य नहीं बना सकता है और ग्राहक कोड एक खाली स्ट्रिंग को पारित कर सकता है, लेकिन कई मामलों में इसे और खाली स्ट्रिंग के बीच अंतर करने और मूल्य नहीं होने के लिए उपयोगी हो सकता है। आपके कमेंट के लिए धन्यवाद। मैं जवाब अपडेट कर दूंगा।
मोजार्ट ब्रोचिनी

2

क्या सूरज अब अपना नहीं है? यह क्या है:
http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Modules-com.sun/istack/com.sun.istack.internal.htm

ऐसा लगता है कि मैंने पिछले कुछ वर्षों में जावा के सभी संस्करणों के साथ पैक किया है।

संपादित करें: जैसा कि नीचे टिप्पणी में कहा गया है, आप शायद इन का उपयोग नहीं करना चाहते हैं। उस स्थिति में, मेरा वोट इंटेलीज जेटब्रेन ऐनोटेशन के लिए है!


10
मुझे नहीं पता कि यह क्या है, लेकिन पैकेज का नाम बड़ा होना चाहिए क्योंकि यह सामान्य उपयोग के लिए नहीं है।
स्टीफन सी

3
एक आम तौर पर com.sun नामस्थान में कक्षाओं का उपयोग करने से मना कर दिया जाता है क्योंकि वे आंतरिक हैं; प्रत्यक्ष उपयोग के लिए नहीं; और उनके भविष्य की उपलब्धता या व्यवहार के लिए कोई गारंटी नहीं है। किसी को सीधे com.sun विरूपण साक्ष्य का उपयोग करने के लिए वास्तव में ठोस मामला होना चाहिए।
luis.espinal

प्लस इस तरह के गरीब HTML प्रारूप में प्रदर्शित कुछ (Java2s.com पर इसे बंद करने के लिए) आपको कुछ लाल झंडे देनी चाहिए :)
luis.espinal

2

IntelliJ के बारे में एक अच्छी बात यह है कि आपको उनके एनोटेशन का उपयोग करने की आवश्यकता नहीं है। आप अपना खुद का लिख ​​सकते हैं, या आप जो भी अन्य उपकरण पसंद करते हैं, उनका उपयोग कर सकते हैं। आप एक प्रकार तक भी सीमित नहीं हैं। यदि आप दो पुस्तकालयों का उपयोग कर रहे हैं जो विभिन्न @NotNull एनोटेशन का उपयोग करते हैं, तो आप इन दोनों का उपयोग करने के लिए IntelliJ को बता सकते हैं। ऐसा करने के लिए, "निरीक्षण कॉन्फ़िगर करें" पर जाएं, "लगातार स्थितियां और अपवाद" निरीक्षण पर क्लिक करें, और "कॉन्फ़िगर निरीक्षणों" बटन पर क्लिक करें। मैं जहाँ भी हो सकता है, मैं Nullness Checker का उपयोग करता हूँ, इसलिए मैंने उन एनोटेशन का उपयोग करने के लिए IntelliJ की स्थापना की, लेकिन आप इसे अन्य किसी भी टूल से काम कर सकते हैं। (अन्य उपकरणों पर मेरी कोई राय नहीं है क्योंकि मैं वर्षों से इंटेलीजे के निरीक्षणों का उपयोग कर रहा हूं, और मैं उनसे प्यार करता हूं।)


1

एक अन्य विकल्प ANTLR 4 के साथ प्रदान किए गए एनोटेशन हैं। पुल अनुरोध # 434 के बाद , युक्त विरूपण साक्ष्य @NotNullऔर @Nullableएनोटेशन में एक एनोटेशन प्रोसेसर शामिल होता है, जो संकलन-समय त्रुटियों और / या चेतावनी देता है, इन घटनाओं में से एक का दुरुपयोग किया जाता है (उदाहरण के लिए, यदि दोनों एक ही आइटम पर लागू होते हैं, या यदि @Nullableएक आदिम प्रकार के साथ आइटम पर लागू किया जाता है)। एनोटेशन प्रोसेसर सॉफ़्टवेयर डेवलपमेंट प्रक्रिया के दौरान अतिरिक्त आश्वासन देता है कि इन एनोटेशन के आवेदन द्वारा बताई गई जानकारी सटीक है, जिसमें विधि वंशानुक्रम के मामले भी शामिल हैं।


1

यदि आप स्प्रिंग फ्रेमवर्क का उपयोग करके अपने आवेदन का निर्माण कर रहे हैं, तो मैं निम्नलिखित निर्भरता में पैक किए गए बीन्स सत्यापनjavax.validation.constraints.NotNull से आने का उपयोग करने का सुझाव दूंगा :

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>

इस एनोटेशन का मुख्य लाभ यह है कि स्प्रिंग एनोटेट किए गए विधि पैरामीटर और क्लास फ़ील्ड दोनों के लिए समर्थन प्रदान करता है javax.validation.constraints.NotNull। समर्थन को सक्षम करने के लिए आपको बस इतना करना है:

  1. बीआईएस सत्यापन और जार के लिए एपीआई जार की आपूर्ति जेएसआर -303 / जेएसआर -349 एनोटेशन के सत्यापनकर्ता के कार्यान्वयन के साथ (जो हाइबरनेट वैलिडेटर 5.x निर्भरता के साथ आता है):

    <dependency>
        <groupId>javax.validation</groupId>
        <artifactId>validation-api</artifactId>
        <version>1.1.0.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.1.Final</version>
    </dependency>
  2. वसंत के संदर्भ में MethodValidationPostProcessor प्रदान करें

      @Configuration
      @ValidationConfig
      public class ValidationConfig implements MyService {
    
            @Bean
            public MethodValidationPostProcessor providePostProcessor() {
                  return new MethodValidationPostProcessor()
            }
      }
  3. अंत में आप स्प्रिंग के साथ अपनी कक्षाओं को एनोटेट करते हैं org.springframework.validation.annotation.Validatedऔर सत्यापन स्वचालित रूप से स्प्रिंग द्वारा नियंत्रित किया जाएगा।

उदाहरण:

@Service
@Validated
public class MyServiceImpl implements MyService {

  @Override
  public Something doSomething(@NotNull String myParameter) {
        // No need to do something like assert myParameter != null  
  }
}

जब आप कॉलिंग विधि doSomething और पैरामीटर मान के रूप में नल पास करते हैं, तो वसंत (HibernateValidator के माध्यम से) फेंक देगा ConstraintViolationException। यहां मनुकाल कार्य की आवश्यकता नहीं है।

आप रिटर्न मानों को भी मान्य कर सकते हैं।

javax.validation.constraints.NotNullबीन्स वैलिडेशन फ्रेमवर्क के लिए आने का एक और महत्वपूर्ण लाभ यह है कि फिलहाल यह अभी भी विकसित है और नए संस्करण 2.0 के लिए नई सुविधाओं की योजना बनाई गई है।

किस बारे में @Nullable? बीन्स वैलिडेशन 1.1 में ऐसा कुछ नहीं है। ठीक है, मैं तर्क दे सकता हूं कि यदि आप उन सभी चीजों की @NotNullतुलना में उपयोग करने का निर्णय लेते हैं जो कि एनोटेट के साथ @NonNullप्रभावी रूप से "अशक्त" नहीं हैं, तो @Nullableएनोटेशन बेकार है।


1
कृपया इसका उपयोग न करें। इसका उपयोग क्रम सत्यापन के लिए किया जाता है, स्थैतिक कोड विश्लेषण पर नहीं। देखें justsomejavaguy.blogspot.com/2011/08/... जानकारी के लिए। स्रोत: @ luis.espinal द्वारा 219 वोटों के साथ DELETED जवाब।
कोपरपॉ

@koppor: मैं असहमत हूं। यदि यह उपयोग के लिए अभिप्रेत नहीं है, तो स्प्रिंग रनटाइम पर इसे क्यों हैंडल करेगा। इसके अलावा बीन्स सत्यापन ढांचे को रनटाइम विश्लेषण के लिए विशुद्ध रूप से एनोटेशन बनाने की अनुमति मिलती है, क्योंकि यह रनटाइम पर कॉन्टेक्स्ट ऑब्जेक्ट (वर्तमान में एनोटेट / मान्य इंस्टेंजे) तक पहुंचने की अनुमति देता है।
वॉकरोस

0

स्प्रिंग 5 में पैकेज स्तर पर @NonNullApi है। यह उस परियोजना के लिए एक सुविधाजनक विकल्प की तरह लगता है जिसमें पहले से ही स्प्रिंग निर्भरताएं हैं। @NonNull और @Nullable के लिए तय किए गए सभी फ़ील्ड, पैरामीटर और रिटर्न मान अलग-अलग जगहों पर लागू किए जा सकते हैं।

फाइल पैकेज-info.java:

@org.springframework.lang.NonNullApi
package com.acme;

https://docs.spring.io/spring-data/commons/docs/current/reference/html/#repositories.nullability.annotations

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.