जावा में एनोटेशन का विस्तार करना क्यों संभव नहीं है?


227

मुझे समझ में नहीं आता है कि जावा एनोटेशन में कोई वंशानुक्रम क्यों नहीं है, सिर्फ जावा कक्षाओं के रूप में। मुझे लगता है कि यह बहुत उपयोगी होगा।

उदाहरण के लिए: मैं जानना चाहता हूं कि क्या दिया गया एनोटेशन एक सत्यापनकर्ता है। इनहेरिटेंस के साथ, मैं यह जानने के लिए कि यह एनोटेशन फैली हुई है, यह जानने के लिए मैं सुपरक्लास के माध्यम से रिफ्लेक्सिवली नेविगेट कर सकता हूं ValidatorAnnotation। अन्यथा, मैं इसे कैसे प्राप्त कर सकता हूं?

तो, क्या कोई मुझे इस डिजाइन निर्णय के लिए एक कारण दे सकता है?


2
ध्यान दें, BTW, कि सभी एनोटेशन का विस्तार होता है java.lang.annotation.Annotation, अर्थात कोई भी एनोटेशन instanceofयह है, हालांकि यह तथ्य स्पष्ट रूप से घोषित नहीं किया गया है।
टॉमस ज़ालूस

जवाबों:


166

इस कारण से कि यह उस तरह से डिज़ाइन नहीं किया गया था जब आप जेएसआर 175 डिज़ाइन FAQ में जवाब पा सकते हैं , जहाँ यह कहता है:

आप एनोटेशन सबटाइपिंग का समर्थन क्यों नहीं करते (जहां एक एनोटेशन प्रकार दूसरे को बढ़ाता है)?

यह एनोटेशन प्रकार प्रणाली को जटिल करता है, और इसे "विशिष्ट उपकरण" लिखने में बहुत अधिक कठिन बनाता है।

...

"विशिष्ट उपकरण" - ऐसे कार्यक्रम जो मनमाने बाहरी कार्यक्रमों के एनोटेशन प्रकारों को जानते हैं। स्टब जनरेटर, उदाहरण के लिए, इस श्रेणी में आते हैं। ये प्रोग्राम एनोटेट कक्षाओं को वर्चुअल मशीन में लोड किए बिना पढ़ेंगे, लेकिन एनोटेशन इंटरफेस को लोड करेंगे।

तो, हाँ मुझे लगता है, कारण यह सिर्फ KISS है। वैसे भी, ऐसा लगता है कि यह मुद्दा (कई अन्य लोगों के साथ) जेएसआर 308 के हिस्से के रूप में देखा जा रहा है , और आप इस कार्यक्षमता के साथ एक वैकल्पिक संकलक भी पा सकते हैं जो पहले से ही माथियास रॉकेन द्वारा विकसित किया गया है ।


67
ठीक है, शायद मैं बेवकूफ हूं, लेकिन मुझे लगता है कि यह केवल "इसे सरल रखने" के लिए एनोटेशन का विस्तार नहीं कर सकता है। कम से कम, जावा डिजाइनरों ने वर्ग विरासत के बारे में एक जैसा नहीं सोचा: P
sinuhepop

2
Java 8 M7, सब-क्लासिंग एनोटेशन का समर्थन नहीं करता है। अफ़सोस की बात है।
सेकी

2
@assylias JEP 104 यह उपवर्ग एनोटेशन को संभव बनाने के बारे में नहीं है। JEP 104 को Java 8 में लागू किया गया था, लेकिन यह अभी भी एनक्लॉज नहीं कर सकता है, (एक एनोटेशन एक और एनोटेशन का विस्तार करें)।
जेस्पर

71

एक्स्टेंसिबल एनोटेशन प्रभावी रूप से एक अन्य प्रकार की प्रणाली को निर्दिष्ट और मुख्य करने का बोझ जोड़ देगा। और यह एक बहुत ही अनोखी प्रकार की प्रणाली होगी, इसलिए आप केवल OO प्रकार का प्रतिमान लागू नहीं कर सकते हैं।

उन सभी मुद्दों पर विचार करें, जब आप एक व्याख्या में बहुरूपता और विरासत का परिचय देते हैं (जैसे कि क्या होता है जब उप-एनोटेशन मेटा-एनोटेशन चश्मा जैसे प्रतिधारण बदल जाता है?)

और यह सब क्या उपयोग-मामले के लिए जटिलता जोड़ा गया?

आप जानना चाहते हैं कि क्या दिया गया एनोटेशन किसी श्रेणी का है?

इसे इस्तेमाल करे:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    String category();
}

@Category(category="validator")
public @interface MyFooBarValidator {

}

जैसा कि आप देख सकते हैं, आप उपलब्ध सुविधाओं का उपयोग करके आसानी से बिना दर्द के एनोटेशन को समूह और वर्गीकृत कर सकते हैं।

तो, KISS जावा भाषा पर एक मेटा-प्रकार प्रकार प्रणाली शुरू नहीं करने के लिए कारण है।

[ps edit]

मैंने स्ट्रिंग का उपयोग केवल प्रदर्शन के लिए किया और एक खुले अंत मेटा एनोटेशन के मद्देनजर। अपनी स्वयं की दी गई परियोजना के लिए, आप स्पष्ट रूप से श्रेणी प्रकारों का उपयोग कर सकते हैं और दिए गए एनोटेशन के लिए कई श्रेणियां ("कई विरासत") निर्दिष्ट कर सकते हैं। ध्यान दें कि मान पूरी तरह से फर्जी हैं और केवल प्रदर्शन उद्देश्यों के लिए हैं:

@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
    AnnotationCategory[] category();
}
public enum AnnotationCategory {
    GENERAL,
    SEMANTICS,
    VALIDATION,
    ETC
}

@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {

}


क्या काम नहीं करेगा गलत:@Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @interface C {}; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @C public @interface F {} class a{ @F public void S() {} } @Test public void blahTest() throws NoSuchMethodException { Method m = a.class.getMethod("S"); System.out.println(m.isAnnotationPresent(C.class)); }
user1615664

हम एक एनोटेशन कर रहे हैं। एक # एस में एनोटेशन है एफ। एफ खुद एन द्वारा एनोटेट किया गया है।
अल्फाजो

हां यह सही है। लेकिन क्या एनोटेशन प्रॉक्सी के माध्यम से पढ़ने के बजाय अधिक सफाई से ऐसा करने का कोई तरीका है?
user1615664

12

एक मायने में आपके पास पहले से ही एनोटेशन - मेटा एनोटेशन के साथ है। यदि आप मेटा जानकारी के साथ एक एनोटेशन की व्याख्या करते हैं, तो यह कई मायनों में एक अतिरिक्त इंटरफ़ेस का विस्तार करने के बराबर है। एनोटेशन इंटरफेस हैं, इसलिए बहुरूपता वास्तव में खेल में नहीं आता है, और चूंकि वे प्रकृति में स्थिर हैं, इसलिए कोई रनटाइम डायनेमिक प्रेषण नहीं हो सकता है।

आपके सत्यापनकर्ता उदाहरण में, आप केवल एनोटेशन पर ही एनोटेट प्रकार प्राप्त कर सकते हैं और देख सकते हैं कि क्या उसके पास एक सत्यापनकर्ता मेटा-एनोटेशन है।

एकमात्र उपयोग मामला मैं देख सकता था कि विरासत में मदद मिलेगी यदि आप सुपर प्रकार से एनोटेशन प्राप्त करने में सक्षम होना चाहते हैं, लेकिन यह जटिलता का एक पूरा गुच्छा जोड़ देगा, क्योंकि किसी दिए गए तरीके या प्रकार पर दो ऐसे एनोटेशन हो सकते हैं। इसका मतलब है कि एक एकल वस्तु के बजाय एक सरणी वापस करना होगा।

इसलिए मुझे लगता है कि अंतिम उत्तर यह है कि उपयोग के मामले गूढ़ हैं और अधिक मानक उपयोग के मामलों को जटिल बनाते हैं जो इसके लायक नहीं हैं।


5

जावा एनोटेशन समर्थन के डिजाइनरों ने जावा समुदाय के अवरोध के लिए कई "सरलीकरण" किए।

  1. कोई भी एनोटेशन उपप्रकार कई जटिल एनोटेशन को अनावश्यक रूप से बदसूरत नहीं बनाता है। किसी के पास केवल एनोटेशन के भीतर एक विशेषता नहीं हो सकती है जो तीन चीजों में से एक को पकड़ सकती है। एक को तीन अलग-अलग विशेषताओं की आवश्यकता होती है, जो डेवलपर्स को भ्रमित करता है और यह सुनिश्चित करने के लिए रनटाइम सत्यापन की आवश्यकता होती है कि तीन में से केवल एक का उपयोग किया जाता है।

  2. प्रति साइट दिए गए प्रकार का केवल एक एनोटेशन। यह पूरी तरह से अनावश्यक संग्रह एनोटेशन पैटर्न को जन्म देता है। @ सत्यापन और @ मान्यताएँ, @ भुगतान और @ छूट इत्यादि।

दूसरे को जावा 8 में रीमेड किया जा रहा है, लेकिन यह बहुत देर हो चुकी है। जावा 5 में जो संभव था, उसके आधार पर कई रूपरेखाएँ लिखी गई हैं और अब ये एपीआई मौसा यहां लंबे समय तक रहने के लिए हैं।


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

3

मुझे इस प्रश्न का उत्तर देने में तीन साल की देरी हो सकती है, लेकिन मुझे यह दिलचस्प लगा क्योंकि मैंने खुद को उसी स्थान पर पाया था। यहाँ मेरा इस पर ले रहा है। आप एनोटेशन को एनम के रूप में देख सकते हैं। वे एक तरह की जानकारी प्रदान करते हैं - इसका उपयोग करें या इसे खो दें।

मेरे पास एक ऐसी स्थिति थी जहां मैं एक वेब-ऐप में GET, POST, PUT और DELETE का अनुकरण करना चाहता था। मैं इतनी बुरी तरह "सुपर" एनोटेशन करना चाहता था जिसे "HTTP_METHOD" कहा जाता था। यह बाद में मुझ पर dawned कि यह कोई फर्क नहीं पड़ा। खैर, मुझे DELETE और PUT (क्योंकि POST और GET वैसे भी उपलब्ध थे) की पहचान करने के लिए HTML फॉर्म में एक छिपे हुए क्षेत्र का उपयोग करके समझौता करना था।

सर्वर-साइड पर, मैंने "_method" नाम के साथ एक छिपे हुए अनुरोध पैरामीटर के लिए देखा। यदि मान PUT या DELETE था, तो यह संबंधित HTTP अनुरोध विधि को ओवररोड करता है। यह कहने के बाद कि, इससे कोई फर्क नहीं पड़ता कि मुझे काम करने के लिए एनोटेशन का विस्तार करने की आवश्यकता है या नहीं। सभी एनोटेशन समान दिखते थे, लेकिन सर्वर साइड पर उनके साथ अलग व्यवहार किया जाता था।

तो आपके मामले में, एनोटेशन को बढ़ाने के लिए खुजली छोड़ें। उन्हें 'मार्कर ’मानें। वे कुछ जानकारी का "प्रतिनिधित्व" करते हैं, और जरूरी नहीं कि कुछ जानकारी का "हेरफेर" करें।


2

एक बात जो मैं सोच सकता था वह यह है कि कई एनोटेशन होने की संभावना है। तो आप एक ही स्थान पर सत्यापनकर्ता और अधिक विशिष्ट एनोटेशन जोड़ सकते हैं। लेकिन मुझसे गलती हो सकती है :)


2

उस बारे में कभी नहीं सोचा लेकिन ... लगता है कि आप सही हैं, एनोटेशन वंशानुक्रम सुविधा के साथ कोई समस्या नहीं है (कम से कम मुझे इसके साथ समस्या नहीं दिखती है)।

'सत्यापनकर्ता' एनोटेशन के साथ अपने उदाहरण के बारे में - तब आप 'मेटा-एनोटेशन' दृष्टिकोण का फायदा उठा सकते हैं । यानी आप पूरे एनोटेशन इंटरफ़ेस में विशेष रूप से मेटा-एनोटेशन लागू करते हैं।


मुझे इस प्रश्न का उत्तर देने में तीन साल की देरी हो सकती है, लेकिन मुझे यह दिलचस्प लगा क्योंकि मैंने खुद को उसी स्थान पर पाया था।
मुख्य

1

मुझे वही समस्या है। नहीं, आप नहीं कर सकते। मैंने कुछ मानकों का सम्मान करने के लिए एनोटेशन में संपत्तियों को लिखने के लिए खुद को 'अनुशासित' किया, इसलिए जब आप एनोटेशन प्राप्त करते हैं तो आप 'स्निफ' कर सकते हैं कि यह किस प्रकार का ओड एनोटेशन है।

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