2011-10-13 19 views
66

मैं एनोटेशन की खोज कर रहा हूं और उस बिंदु पर आया जहां कुछ एनोटेशन में उनके बीच पदानुक्रम होता है।क्या जावा में एनोटेशन विरासत की तरह कुछ है?

मैं कार्ड के लिए पृष्ठभूमि में कोड उत्पन्न करने के लिए एनोटेशन का उपयोग कर रहा हूं। अलग-अलग कार्ड प्रकार हैं (इस प्रकार अलग-अलग कोड और एनोटेशन) लेकिन कुछ ऐसे तत्व हैं जो उनके नाम के समान हैं।

@Target(value = {ElementType.TYPE}) 
public @interface Move extends Page{ 
String method1(); 
String method2(); 
} 

और यह आम एनोटेशन होगा:

@Target(value = {ElementType.TYPE}) 
public @interface Page{ 
String method3(); 
} 

उदाहरण में ऊपर मैं method3 वारिस में ले जाएँ उम्मीद होती है, लेकिन मैं एक चेतावनी कह रही है कि फैली एनोटेशन के साथ मान्य नहीं है मिलता है। मैं एक एनोटेशन एक सामान्य आधार को विस्तारित करने की कोशिश कर रहा था लेकिन यह काम नहीं करता है। क्या यह भी संभव है या सिर्फ एक डिजाइन मुद्दा है?

+0

एनोटेशन विरासत एनोटेशन के आधार पर डीएसएल बनाने के लिए जरूरी है। इस तरह की करुणा है कि एनोटेशन विरासत समर्थित नहीं है। – Ceki

+0

मैं सहमत हूं, ऐसा करने के लिए एक प्राकृतिक चीज़ की तरह लगता है। विशेष रूप से जावा पर विरासत को समझने के बाद, आप उम्मीद करते हैं कि यह सब कुछ पर लागू हो। – javydreamercsw

उत्तर

49

दुर्भाग्य से, नहीं। जाहिर है, इसमें ऐसे कार्यक्रमों के साथ कुछ करना है जो कक्षा में एनोटेशन को बिना किसी तरीके से पढ़े पढ़ते हैं। Why is not possible to extend annotations in Java?

हालांकि, अगर उनके एनोटेशन @Inherited हैं तो उनके सुपरक्लास की टिप्पणियों का उत्तराधिकारी होता है।

@Move 
@Page 
public class myAwesomeClass {} 

वहाँ कुछ कारण यह है कि आपके लिए काम नहीं होता है:

इसके अलावा, जब तक कि आप बातचीत करने के लिए उन तरीकों की जरूरत है, तो आप सिर्फ अपनी कक्षा पर टिप्पणियों का ढेर कर सकता है?

+1

यही मैंने सोचा था लेकिन मैं चीजों को सरल बनाने की कोशिश कर रहा था। हो सकता है कि आम एक को एक अमूर्त वर्ग में लागू करना चाल करे ... – javydreamercsw

+1

हाँ, यह भी बहुत चालाक लग रहा था। सौभाग्य! – andronikus

33

आप विरासत के बजाय आधार एनोटेशन के साथ अपनी एनोटेशन को एनोटेट कर सकते हैं। यह used in Spring framework है।

एक उदाहरण

@Target(value = {ElementType.ANNOTATION_TYPE}) 
public @interface Vehicle { 
} 

@Target(value = {ElementType.TYPE}) 
@Vehicle 
public @interface Car { 
} 

@Car 
class Foo { 
} 

तो आप देख सकते हैं एक वर्ग VehicleSpring's AnnotationUtils उपयोग करने के साथ टिप्पणी की जाती है देने के लिए:

public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) { 
    return findAnnotation(clazz, annotationType, new HashSet<Annotation>()); 
} 

@SuppressWarnings("unchecked") 
private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType, Set<Annotation> visited) { 
    try { 
     Annotation[] anns = clazz.getDeclaredAnnotations(); 
     for (Annotation ann : anns) { 
      if (ann.annotationType() == annotationType) { 
       return (A) ann; 
      } 
     } 
     for (Annotation ann : anns) { 
      if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) { 
       A annotation = findAnnotation(ann.annotationType(), annotationType, visited); 
       if (annotation != null) { 
        return annotation; 
       } 
      } 
     } 
    } 
    catch (Exception ex) { 
     handleIntrospectionFailure(clazz, ex); 
     return null; 
    } 

    for (Class<?> ifc : clazz.getInterfaces()) { 
     A annotation = findAnnotation(ifc, annotationType, visited); 
     if (annotation != null) { 
      return annotation; 
     } 
    } 

    Class<?> superclass = clazz.getSuperclass(); 
    if (superclass == null || Object.class == superclass) { 
     return null; 
    } 
    return findAnnotation(superclass, annotationType, visited); 
} 

AnnotationUtils:

Vehicle vehicleAnnotation = AnnotationUtils.findAnnotation (Foo.class, Vehicle.class); 
boolean isAnnotated = vehicleAnnotation != null; 

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

+11

कृपया इस तरह की टिप्पणियों को संसाधित करने का विवरण शामिल करें। –

+1

आप स्प्रिंग्स एनोटेशन यूटिल्स का उपयोग कर सकते हैं। फाइनएनोटेशन (..), देखें: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/annotation/AnnotationUtils.html#findAnotation-java .lang.Class-java.lang.Class- – rgrebski

5

एनोटोटिंग एनोटेशन के ग्रिगोरीस के जवाब के अलावा।

आप उदाहरण देख सकते हैं उदा। इस पाश से एक @Qualifier एनोटेशन (या एक एनोटेशन @Qualifier साथ एनोटेट) युक्त करने के लिए तरीके:

for (Annotation a : method.getAnnotations()) { 
    if (a.annotationType().isAnnotationPresent(Qualifier.class)) { 
     System.out.println("found @Qualifier annotation");//found annotation having Qualifier annotation itself 
    } 
} 

क्या आप मूल रूप से कर रहे हैं, विधि पर और उन एनोटेशन आप प्राप्त की वर्तमान सभी एनोटेशन प्राप्त करने के लिए है उनके प्रकार और उन प्रकारों की जांच करें यदि वे @Qualifier के साथ एनोटेटेड हैं। आपकी एनोटेशन को लक्ष्य होना आवश्यक है। इस काम को प्राप्त करने के लिए एन्नोटेशन_ टाइप सक्षम भी है।

+0

यह ग्रेगोरिया के उत्तर से अलग कैसे है? –

संबंधित मुद्दे