2014-12-22 4 views
9

जावा 8 में कस्टम टाइप एनोटेशन का उपयोग कैसे करें जावा 8 में टाइप एनोटेशन (JSR 308) नामक सुविधा है। मैं ऑब्जेक्ट मैपर फ्रेमवर्क के लिए सरल ऑब्जेक्ट के लिए इसका उपयोग करना चाहता हूं। मैं इसजावा

@Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ExpectedType { 
    public Class<?> value(); 
} 

तरह एनोटेशन @ExpectedType को परिभाषित और फिर इस तरह मेरी कोड में उपयोग करना चाहते हैं:

public class SomeServiceImpl() { 
    public @ExpectedType(ObjectA_DTO.class) IObjectA doSomething(@ExpectedType(ObjectA_Entity.class) IObjectA obj) { 
     return (ObjectA_Entity) obj; // it's correct 
    } 
} 

IObjectA कक्षाएं ObjectA_DTO और ObjectA_Entity द्वारा कार्यान्वित एक अंतरफलक है।

// it's correct 
assert someService.doSomething(new ObjectA_DTO()).getClass() == ObjectA_DTO.class; 

मैं वस्तु नक्शाकार उपयोग करने के लिए SomeServiceImpl तरीकों में से परिवर्तन कॉल करना चाहते हैं: सेवा मैं चाहते हैं इस तरह से उपयोग करने के लिए। यह JSR 269 या एओपी द्वारा जेनरेट कोड द्वारा हासिल किया जा सकता है।

समस्या यह है कि मैंने सरल एनोटेशन प्रोसेसर लिखा है और यह टाइप एनोटेशन को संभाल नहीं करता है। सरल एनोटेशन प्रोसेसर के स्रोत इस तरह दिखता है:

@SupportedAnnotationTypes("*") 
@SupportedSourceVersion(SourceVersion.RELEASE_8) 
public class SimpleAnnotationsProcessor extends AbstractProcessor { 

    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
     Messager messager = processingEnv.getMessager(); 
     try { 
      for (TypeElement e : annotations) { 
       messager.printMessage(Diagnostic.Kind.NOTE, e.toString()); 
       for (Element elem : roundEnv.getElementsAnnotatedWith(e)) { 
        messager.printMessage(Diagnostic.Kind.NOTE, elem.toString()); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return true; 
    } 
} 

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

+0

इस्तेमाल किया जा सकता मुझे लगता है मैं स्पष्ट नहीं क्या लक्ष्य आप प्राप्त करना चाहते हैं हूँ। क्यों न केवल विधि हस्ताक्षर 'ऑब्जेक्टए_DTO doSomething (ObjectA_Entity)' बनाओ, अगर आप ऐसा करने की अपेक्षा कर रहे हैं? –

+0

विधि हस्ताक्षर इस तरह से नहीं हो सकता है, क्योंकि मैं इस 'someService.doSomething (new ObjectA_DTO()) जैसे सेवा उदाहरण का उपयोग करना चाहता हूं। मैं ऑब्जेक्ट मैपर को 'ObjectA_DEO' को 'ऑब्जेक्टए_एन्टीटी' पर मैप करने के लिए कार्यान्वित करना चाहता हूं और एनोटेशन टाइप करें @ एक्सपेक्टेड टाइप टाइप प्रकार को परिभाषित करता है। यही कारण है कि हस्ताक्षर को 'IObjectA do कुछ (IObjectA)' होना चाहिए। –

+0

मैंने अभी आपके प्रश्न को पास करने में पकड़ा ... मैंने उत्पाद लाइन विकास पर एक सेमेस्टर प्रोजेक्ट किया जहां हमने एनोटेशन को संसाधित किया। अभी के लिए, मैं आपको इस महत्वपूर्ण ट्यूटोरियल के साथ छोड़ दूंगा जो वास्तव में मुझे विषय पर जा रहा है (आप कोड पीढ़ी के बारे में भाग 3 छोड़ सकते हैं) - https://deors.wordpress.com/2011/09/26/annotation-types/ बाद में, मैं प्रगति के लिए इस पोस्ट को दोबारा जांचूंगा। – ThisClark

उत्तर

2

मुझे यकीन है कि मैं समझता हूँ कि आप क्या हासिल करने की कोशिश, लेकिन यहाँ है कि कैसे आप जावा प्रतिबिंब एपीआई के साथ अपनी टिप्पणियों को एक्सेस कर सकते हैं एक उदाहरण है नहीं कर रहा हूँ:

package test; 

import java.lang.annotation.Annotation; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
import java.lang.reflect.AnnotatedType; 
import java.lang.reflect.Method; 

public class TypeParameterTest { 

    @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 
    @Retention(RetentionPolicy.RUNTIME) 
    public @interface ExpectedType { 
     public Class<?> value(); 
    } 

    public static interface IObjectA {} 

    public static class ObjectA_DTO implements IObjectA {} 

    public static class ObjectA_Entity implements IObjectA {} 

    public static class SomeServiceImpl { 
     public @ExpectedType(ObjectA_DTO.class) IObjectA doSomething(@ExpectedType(ObjectA_Entity.class) IObjectA obj) { 
      return (ObjectA_Entity) obj; 
     } 
    } 

    public static void main(String[] args) throws NoSuchMethodException, SecurityException { 
     Method m = SomeServiceImpl.class.getMethod("doSomething", IObjectA.class); 
     AnnotatedType returnType = m.getAnnotatedReturnType(); 
     Annotation returnTypeAnnotation = returnType.getAnnotation(ExpectedType.class); 
     System.out.println(returnTypeAnnotation); 

     AnnotatedType[] parameters = m.getAnnotatedParameterTypes(); 
     for (AnnotatedType p : parameters) { 
      Annotation parameterAnnotation = p.getAnnotation(ExpectedType.class); 
      System.out.println(parameterAnnotation); 
     } 
    } 
} 

उत्पादन इस तरह दिखता है:

@test.TypeParameterTest$ExpectedType(value=class test.TypeParameterTest$ObjectA_DTO) 
@test.TypeParameterTest$ExpectedType(value=class test.TypeParameterTest$ObjectA_Entity) 

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

+0

मैं एनोटेशन प्रोसेसर का उपयोग करके ऐसा करना चाहता हूं क्योंकि यह रनटाइम में तेज़ हो सकता है, फिर भी प्रतिबिंब, वैसे भी मैं आपका जवाब स्वीकार करता हूं। चेकर फ्रेमवर्क एनोटेशन प्रोसेसर से टाइप एनोटेशन पढ़ सकते हैं (बाइट कोड से नहीं)। क्या आप जानते हैं कि यह कैसा चल रहा है? –

+0

क्षमा करें, मैंने अभी तक परीक्षक ढांचे का उपयोग नहीं किया है। मुझे विश्वास नहीं है कि एनोटेशन प्रोसेसर प्रतिबिंब का उपयोग करने से तेज होंगे (हालांकि सुनिश्चित नहीं है)। लेकिन मैं वास्तविक प्रदर्शन मुद्दों में भाग लेने से पहले किसी भी अनुकूलन के बारे में नहीं सोचूंगा। आम तौर पर प्रतिबिंब पर्याप्त तेज़ है ... – Balder

+0

क्या आप जानते हैं कि प्रतिबिंब एपीआई के माध्यम से स्थानीय चर के साथ उपयोग किए जाने वाले प्रकारों के लिए प्रकार एनोटेशन का उपयोग कैसे करें? इस तरह कुछ '@NotNull स्ट्रिंग str = "";' या 'स्ट्रिंग स्ट्र = (@Nullable स्ट्रिंग) शून्य; विधि विधि के अंदर? मैं इस तरह '@ अपेक्षित टाइप 'एनोटेशन का उपयोग करना चाहूंगा:' ऑब्जेक्टए_DTO aDto = (@ExpectedType ObjectA_DTO) कुछ सेवा .do कुछ (...);' –

0

मुझे लगता है कि आप विभिन्न उपकरणों द्वारा "संकलन" समय पर उपयोग के विरुद्ध रन टाइम पर एनोटेशन के उपयोग को मिश्रित कर रहे हैं। Processor इंटरफ़ेस उपकरण (कंपाइलर, जावाडॉक जेनरेटर) में उपयोग के लिए है, आपके रनटाइम कोड में नहीं।

+0

मैं बेहतर प्रदर्शन के लिए कोड जेनरेट करना चाहता हूं जैसे मैपस्ट्रक्चर या लॉमोकॉक रनटाइम पर जावा प्रतिबिंब का उपयोग करना। –

0
@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface SearchDefinition { 

    public String identifier() default ""; 

} 

@SearchDefinition - कहीं भी

+1

यह उत्तर पूरी तरह गलत है '@ लक्ष्य (ElementType.FIELD)' एनोटेशन का कहीं भी उपयोग नहीं किया जा सकता है। इसका उपयोग केवल कक्षा क्षेत्रों के साथ किया जा सकता है। यदि '@ target' छोड़ा गया है तो इसे टाइप कास्ट (' (@SearchDefinition String) "abc" ') या सामान्य प्रकार ('सूची <@ खोज परिभाषा स्ट्रिंग>') को छोड़कर लगभग कहीं भी उपयोग किया जा सकता है। –