2010-07-19 14 views
19

दोस्तों को एनोटेशन को प्रत्यक्ष पैरामीटर के रूप में पास करने का कोई तरीका है (बल्कि सभी प्रतिबिंब ओवरहेड करके)? उदाहरण के लिए, निम्नलिखित कोड में, मेरे पास एक एनोटेशन नंबर है जो एक int मान रखता है, मैं addImpl विधि में पैरामीटर के रूप में पास करना चाहता हूं, मैं यह कैसे कर सकता हूं (प्रतिबिंब के अलावा)?जावा एनोटेशन को पैरामीटर के रूप में पास करने का कोई तरीका है?

कोड स्निपेट:

@Retention(RetentionPolicy.RUNTIME) 
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) 
public @interface Number { 
    int value(); 
} 

public void add(int x2) { 
    addImpl(@Number(value = 10) lol, x2); 
} 

public void addImpl(Number a, int b) { 
    System.out.println(a.value() + b); 
} 

public static void main(String[] args) { 
    new TestClass().add(3); 
} 
+4

संख्या एक नियमित रूप से वर्ग एक एनोटेशन के बजाय के रूप में परिभाषित किया गया है क्यों: JSR 303 सत्यापनकर्ता का उदाहरण परीक्षण के लिए ऐसा दिखाई दे सकता? एनोटेशन का उद्देश्य संकलन समय पर मेटा-डेटा को स्थिर रूप से जोड़ने के लिए है। यदि वह आपका लक्ष्य नहीं है, तो एनोटेशन के रूप में परिभाषित करने का कारण क्या है? – jthg

+0

संख्या सिर्फ एक नमूना चीज है जो मैं आया था, मैं प्रोटोकॉल इन्स आसान बनाने के लिए ऐसा कर रहा हूं;) –

उत्तर

17

हाँ, आप इस तरह एनोटेशन के आसपास पारित कर सकते हैं (जैसे कि वे सामान्य इंटरफेस थे)।

एकमात्र चीज जो आप नहीं कर सकते हैं वह रनटाइम पर उस इंटरफ़ेस के उदाहरण बनाना है। आप केवल मौजूदा एनोटेशन ले सकते हैं और उन्हें पास कर सकते हैं।

import java.lang.annotation.*; 

public class Example { 

    @Retention(RetentionPolicy.RUNTIME) 
    @Target(ElementType.METHOD) 
    public static @interface Number { 
     int value(); 
    } 

    @Number(value = 42) 
    public int adder(final int b) throws SecurityException, NoSuchMethodException { 
     Number number = getClass().getMethod("adder", int.class).getAnnotation(Number.class); 
     return addImpl(number, b); 
    } 

    public int addImpl(final Number a, final int b) { 
     return a.value() + b; 
    } 

    public static void main(final String[] args) throws SecurityException, NoSuchMethodException { 
     System.out.println(new Example().adder(0)); 
    } 
} 
+1

ओकाय - क्या इसके लिए कुछ वास्तविक दुनिया के उपयोग के मामले हैं? –

+1

@Andreas_D: निश्चित रूप से, जहां भी आप कुछ एनोटेशन पर प्रतिक्रिया करते हैं, आप कोड को आसानी से कई तरीकों (या यहां तक ​​कि कक्षाओं) में अपना काम करने के लिए प्रतिक्रिया दे सकते हैं और एनोटेशन के आसपास गुजरने में सक्षम होना बहुत उपयोगी हो सकता है। –

+2

एक और उपयोग केस एक जेएसआर 303 सत्यापनकर्ता का परीक्षण किया जा सकता है। इसमें विधि प्रारंभ है() जो एनोटेशन लेता है। –

3

मेरी जानकारी के अनुसार करने के लिए, वहाँ एक जैसी कोई चीज नहीं है "एनोटेशन शाब्दिक" के रूप में आप अपने add कार्यान्वयन में उपयोग करना चाहते हैं।

मुझे लगता है कि इसकी निकटतम बात java.lang.annotation.Annotation के पैरामीटर को लेने के लिए विधि घोषित करना होगा - लेकिन फिर भी आपको कक्षा/विधि वस्तुओं से प्रतिबिंब के माध्यम से उन उदाहरणों को प्राप्त करने की आवश्यकता होगी। के बाद से संख्या मूल रूप से एक अंतरफलक है, तो आप एक अनाम वर्ग कि है कि इंटरफ़ेस को लागू करता है का एक उदाहरण बना सकते हैं और विधि के लिए कि पारित करने के लिए है

public void add(int x2) { 
    addImpl(new Number() { 

     @Override 
     public int value() { 
      return 10; 
     } 

     @Override 
     public Class<? extends Annotation> annotationType() { 
      return Number.class; 
     } 
    }, x2); 
} 

:

8

आप इसे पसंद कर सकते हैं।

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

+0

संख्या सिर्फ एक नमूना है: 3 –

+0

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

1

संख्या भी एक अच्छा पुराना इंटरफ़ेस है, आप एक ठोस वर्ग को कार्यान्वित कर सकते हैं।

दोस्तों, यह उपयोगी है। जबकि एक मॉड्यूल ज्यादातर एनोटेशन के साथ सौदा करता है जो संकलन समय पर तय होते हैं, कभी-कभी हमें इसे अन्य स्रोतों (जैसे एक्सएमएल, गश!) से रनटाइम पर प्राप्त अन्य जानकारी को खिलाने की आवश्यकता होती है। हम चीज़ को ओवर-आर्किटेक्ट कर सकते हैं, या हम बस रनटाइम बना सकते हैं एनोटियन प्रकार का ऑब्जेक्ट।

+1

अपनी कक्षाओं में एनोटेशन इंटरफेस लागू करना कम से कम एक कोड गंध है। –

+0

निपुणता की गंध अच्छी है। – irreputable

1

यदि आपको परीक्षण में एनोटेशन पास करने की आवश्यकता है, तो आप इसका मज़ाक उड़ा सकते हैं।

public void test() { 
    final TextLengthValidator validator = new TextLengthValidator(); 
    validator.initialize(mock(TextLength.class)); 
    final boolean valid = validator.isValid("some text", mock(ConstraintValidatorContext.class)); 
    assertThat(valid, is(true)); 
} 
संबंधित मुद्दे

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