जावा क्लासेस को लागू इंटरफेस से एनोटेशन क्यों नहीं मिलते हैं?


108

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

यह भी ध्यान दें कि यह मेटा-एनोटेशन केवल एनोटेशन को सुपरक्लास से विरासत में मिला है; लागू इंटरफेस पर एनोटेशन का कोई प्रभाव नहीं पड़ता है।

इसका क्या कारण रह सकता है? सभी इंटरफेस को पता होना कि किसी ऑब्जेक्ट की क्लास रनटाइम में लागू होती है, ऐसा करना मुश्किल नहीं है क्योंकि इस फैसले के पीछे एक अच्छा कारण होना चाहिए।

जवाबों:


130

मैं कहता हूँ कि कारण यह है कि अन्यथा एक बहु-विरासत समस्या उत्पन्न होगी।

उदाहरण:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Inherited
public @interface Baz { String value(); }

public interface Foo{
    @Baz("baz") void doStuff();
}

public interface Bar{
    @Baz("phleem") void doStuff();
}

public class Flipp{
    @Baz("flopp") public void doStuff(){}
}

public class MyClass extends Flipp implements Foo, Bar{}

अगर मैं ऐसा करता हूं:

MyClass.class.getMethod("doStuff").getAnnotation(Baz.class).value()

क्या परिणाम होने जा रहा है? 'बाज', 'फलीम' या 'फ्लॉप'?


इस कारण से, इंटरफेस पर एनोटेशन शायद ही कभी उपयोगी होते हैं।


9
इंटरफेस पर एनोटेशन केवल तभी उपयोगी होते हैं जब आपके पास एक फ्रेमवर्क होता है जो उनका समर्थन करता है। इस उदाहरण में BTW getAnnotation () रिटर्न अशक्त;)
पीटर लॉरी

6
मुझे नहीं पता, लोग। इस मामले में (यदि टाइपो नहीं था), तो मैं एक समान The field value is ambiguous.संकलक त्रुटि की अपेक्षा करूंगा जैसे दो इंटरफेस अलग-अलग मूल्यों के साथ एक ही निरंतर की घोषणा करते हैं। मुझे पता है कि यह एक क्षेत्र नहीं है, लेकिन एनोटेशन मूल्यों को सभी संकलन समय पर हल किया जाता है, न? हमारे यहां जो सुविधा गायब है, वह कई मामलों में सुपर-सहायक होगी। एक पुरानी पोस्ट को पुनर्जीवित करने के बारे में क्षमा करें, :)।
पेट्र जेनेक

7
@Slanec वसंत स्रोतों को देखने के तरीके पर एक नज़र रखता है कि वसंत लोगों ने इन समस्याओं के आसपास कैसे काम किया। देखें AnnotationUtils.findAnnotation (विधि, annotationType)
शॉन पैट्रिक फ्लोयड

1
मैं इसके समान कुछ लिखने पर विचार कर रहा था। किसी तरह की साधारण कैशिंग के साथ, यह मेरे लिए जाने का एक तरीका लगता है। धन्यवाद! ऊपर दिए गए उदाहरण में, यह Foo'एनोटेशन' होगा ( MyClassएक नहीं है, तो इंटरफेस को खोजा जाता है और उस क्रम में लिया जाता है जिसमें वे हैं implements) और इसलिए "बाज" प्रिंट करें। ठंडा।
पेट्र जेनेक

2
@ सच है, यह सिर्फ 2 साल लग गए किसी को उस टाइपो को स्पॉट करने के लिए :-)
सीन पैट्रिक फ्लोयड

35

से जावाडोक @Inherited के लिए:

इंगित करता है कि एक एनोटेशन प्रकार स्वचालित रूप से विरासत में मिला है। यदि एक इनहेरिटेड मेटा-एनोटेशन किसी एनोटेशन प्रकार की घोषणा पर मौजूद होता है, और उपयोगकर्ता किसी क्लास डिक्लेरेशन पर एनोटेशन प्रकार पर सवाल उठाता है, और इस प्रकार के लिए क्लास डिक्लेरेशन में कोई एनोटेशन नहीं होता है, तो क्लास का सुपरटेस्ट स्वचालित रूप से एनोटेशन प्रकार के लिए क्वियर किया जाएगा। यह प्रक्रिया तब तक दोहराई जाएगी जब तक कि इस प्रकार के लिए एक एनोटेशन नहीं मिलता है, या वर्ग पदानुक्रम (ऑब्जेक्ट) के शीर्ष पर पहुंच जाता है। यदि किसी सुपरक्लास के पास इस प्रकार के लिए एनोटेशन नहीं है, तो क्वेरी इंगित करेगी कि प्रश्न में वर्ग के पास ऐसी कोई एनोटेशन नहीं है। ध्यान दें कि इस मेटा-एनोटेशन प्रकार का कोई प्रभाव नहीं पड़ता है यदि एनोटेट प्रकार का उपयोग किसी वर्ग के अलावा किसी अन्य चीज़ को एनोटेट करने के लिए किया जाता है। यह भी ध्यान दें कि यह मेटा-एनोटेशन केवल एनोटेशन को सुपरक्लास से विरासत में मिला है;

दूसरी ओर, जेएसआर 305 सत्यापनकर्ता कुछ प्रकार की विरासत खोज करते हैं। यदि आपके पास कक्षाओं का एक पदानुक्रम है:

//Person.java
@Nonnull
 public Integer getAge() {...}

//Student.java (inherits from Person)
@Min(5)
public Integer getAge() {...}

फिर प्रभावी मान्यताएँ Student.getAge()हैं @Nonnull @Min(5)@Nonnullकोई @Inheritedमेटा-एनोटेशन नहीं है।


4
यह एक चयनित उत्तर होना चाहिए
आंद्रेजे पुर्तक

3
आपका उदाहरण आपके उत्तर का खंडन करता है, जो कहता है कि @Inheritedकक्षा के अलावा किसी भी चीज पर कोई प्रभाव नहीं है
ओलेग मिखेव

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