2009-11-26 15 views
29

एनोटेटेड विधि पर एनोटेशन के मूल्य को मैं कैसे प्राप्त कर सकता हूं ??जावा एनोटेशन विशेषता पुनर्प्राप्त करें

मेरे पास है:

@myAnnotation(attribute1 = value1, attibute2 = value2) 
public void myMethod() 
{ 
    //I want to get value1 here 
} 
+0

क्या आप जो कुछ हासिल करने की कोशिश कर रहे हैं उस पर अधिक जानकारी प्रदान कर सकते हैं? – Carl

+0

जैसा कि मैंने कहा है, मैं कोड –

+0

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

उत्तर

43
  1. प्राप्त Method उदाहरण।
  2. एनोटेशन प्राप्त करें।
  3. एनोटेशन विशेषता मान प्राप्त करें।

कुछ की तरह:

Method m = getClass().getMethod("myMethod"); 
MyAnnotation a = m.getAnnotation(MyAnnotation.class); 
MyValueType value1 = a.attribute1(); 

आप को पकड़ने के लिए/संभाल उचित अपवाद, ज़ाहिर है की आवश्यकता होगी। ऊपर समझती है कि आप वास्तव में वर्तमान वर्ग से विधि को पुन: प्राप्त कर रहे हैं (Class.forName() अन्यथा साथ getClass() की जगह) और प्रश्न में विधि सार्वजनिक है (उपयोग getDeclaredMethods() यदि यह मामला नहीं है)

+0

यह नहीं होना चाहिए "MyValueType value1 = a.getAttribute1();" –

+0

या अधिक जैसे "a.attribute()' – Bozho

+0

निश्चित रूप से होना चाहिए। धन्यवाद, – ChssPly76

19

दो महत्वपूर्ण बातें:

  • वहाँ वर्तमान विधि प्राप्त करने का कोई तरीका नहीं है, उदाहरण के लिए getClass() जैसे getMethod() नहीं है। इसलिए, अपनी एनोटेशन तक पहुंचने वाली विधि को अपना नाम जानना होगा।
  • एनोटेशन की अवधारण नीति RUNTIME पर सेट की जानी चाहिए, ताकि आप रनटाइम पर एनोटेशन तक पहुंच सकें। डिफ़ॉल्ट संकलन-समय है, जिसका अर्थ है कि एनोटेशन कक्षा फ़ाइल में उपलब्ध हैं, लेकिन प्रतिबिंब का उपयोग करके रनटाइम पर पहुंचा नहीं जा सकता है।

पूर्ण उदाहरण:

@Retention(RetentionPolicy.RUNTIME) 
public static @interface MyAnnotation { 
    String value1(); 

    int value2(); 
} 

@Test 
@MyAnnotation(value1 = "Foo", value2 = 1337) 
public void testAnnotation() throws Exception { 
    Method[] methods = getClass().getMethods(); 
    Method method = methods[0]; 
    assertEquals("testAnnotation", method.getName()); 
    MyAnnotation annotation = method.getAnnotation(MyAnnotation.class); 
    assertEquals("Foo", annotation.value1()); 
    assertEquals(1337, annotation.value2()); 
} 
+4

वर्तमान विधि प्राप्त करने का एक तरीका है। या तो 'Thread.currentThread()। getStackTrace() [2] .getMethodName() 'या' नया थ्रोबल()। FillInStackTrace()। GetStackTrace() [0]।getMethodName() 'इसे करना चाहिए। – ChssPly76

+1

+1 का उल्लेख करने के लिए प्रतिधारण – basszero

+1

@ ChssPly76, एक स्टैकट्रस का निर्माण पूरी तरह से विश्वसनीय नहीं है, क्योंकि जावाडॉक्स का उल्लेख है: "कुछ वर्चुअल मशीनें, कुछ परिस्थितियों में, स्टैक ट्रेस से एक या अधिक स्टैक फ्रेम को छोड़ सकती हैं। चरम मामले में, एक वर्चुअल मशीन जिसमें कोई स्टैक ट्रेस जानकारी नहीं है [...] को इस विधि से शून्य-लंबाई सरणी वापस करने की अनुमति है। " – gustafc

1

@mhaller: अपनी पोस्ट पर एक टिप्पणी के लिए बहुत लंबा थोड़ा। जाहिर है अतिभारित तरीकों से निपटने के लिए और अधिक परिशोधित करने की आवश्यकता होगी, लेकिन यह असंभव नहीं है .:

import java.lang.reflect.Method; 

public class Hack { 
    public static void main (String[] args) { 
     (new Hack()).foobar(); 
    } 
    public void foobar() { 
     Method here = getCurrentMethod(this); 
     System.out.format("And here we are: %s\n", here); 
    } 
    public static final Method getCurrentMethod(Object o) { 
     String s = Thread.currentThread().getStackTrace()[2].getMethodName(); 
     Method cm = null; 
     for(Method m : o.getClass().getMethods()){ 
      if(m.getName().equals(s)){ 
       cm = m; break; 
      } 
     } 
     return cm; 
    } 
} 

[संपादित: क्रेडिट/मुख्य() में त्रुटि खोलना के लिए अलेक्सेंद्र Priymak करने के लिए धन्यवाद]

+3

मुझे एहसास है कि यदि आप वास्तव में उत्पादन कोड में ऐसा करते हैं, तो यह आपकी पुरानी आत्मा को भस्म करने के लिए महान पुराने लोगों को बुलाता है! –

+0

@ स्किप हेड - क्यों? यहां पर दो चीजें सावधान रहेंगी - (1) सिद्धांत में ** सरणी सूचकांक ** कुछ जेवीएम पर 2 से अलग हो सकता है लेकिन पूरे ट्रेस के माध्यम से घूमना आसान है; (2) यह अधिभारित तरीकों के लिए काम नहीं करेगा; आप जादुस्त्री के साथ कुछ काले जादू कर सकते हैं ताकि लाइन नंबर पर आधारित सही अनुमान लगाया जा सके लेकिन वास्तव में कुछ हद तक iffy है। अन्य तो, हालांकि, यह पूरी तरह से काम करता है - आपको लगता है कि स्टैक निशान कैसे काम करते हैं? – ChssPly76

+0

@ ChssPly76: पूरे निशान को चलाने की आवश्यकता नहीं है। ट्रेस विधि शीर्ष पर शुरू होती है और जब तक यह खुद को पाता है तब तक चलता है। और कॉलर अगली है। – alphazero

0

प्राप्त करने के लिए वर्तमान विधि, इस कोड का उपयोग करने का प्रयास करें:

Thread.currentThread().getStackTrace()[1].getClassName().toString()+\".\"+Thread.currentThread().getStackTrace()[1].getMethodName().toString() 
संबंधित मुद्दे