2010-05-07 11 views
5

मेरे पास Class<? extends Annotation> है और newInstance() पर कॉल करने का प्रयास किया लेकिन जावा ने मुझे स्पष्ट कारण के लिए चिल्लाया कि मैं एक इंटरफ़ेस को तुरंत चालू नहीं कर सकता। लेकिन मुझे पता है कि EasyMock जैसे ढांचे इंटरफेस को तुरंत चालू करने में सक्षम हैं। मेरे Class से पूरी तरह से गूंगा Annotation उदाहरण प्राप्त करने के लिए क्या होगा?क्या कक्षा को दिए गए जावा एनोटेशन को तुरंत चालू करना संभव है? एनोटेशन बढ़ाता है>?

उत्तर

7

नकली ढांचे इंटरफेस को तत्काल नहीं करते हैं, वे कक्षाओं का निर्माण करते हैं जो उन्हें रनटाइम पर फ्लाई पर लागू करते हैं। आप जो करना चाहते हैं उसके लिए आपको this javadoc enlightening मिल सकता है!

2

आप ऐसी कक्षा का उदाहरण नहीं बना सकते जो पूरी तरह से निर्दिष्ट नहीं है।

समझाने के लिए, प्रकार Class<Object> के एक वर्ग पर newInstance() बुला निश्चित रूप से एक वस्तु बन जाएगा, लेकिन प्रकार Class<?> के एक वर्ग पर newInstance() बुला संकलक सोच जो संभावनाओं की पूरे ब्रह्मांड से बाहर वर्ग यह निर्माण करना चाहिए छोड़ना होगा।

सिर्फ इसलिए कि आप क्षेत्र नीचे सिर्फ ? के बजाय कि निर्दिष्ट करके थोड़ा संकुचित है, तो आप एक ? कि Annotation फैली मतलब यह नहीं है कि आप वास्तव में निर्माण करने के लिए एक विशेष वर्ग नाम दिया है चाहता हूँ। ? extends Annotation का अर्थ है "कुछ वर्ग जो Annotation बढ़ाता है" सटीक कक्षा का नाम देने के बिना, क्लासलोडर यह नहीं समझ सकता कि कौन से कन्स्ट्रक्टर को कॉल करना है, क्योंकि Annotation तक बढ़ने वाले वर्गों की संख्या की कोई सीमा नहीं है।

EasyMock इंटरफेस को तुरंत चालू नहीं करता है। मैं ढांचे से परिचित नहीं हूं, लेकिन यह संभवतः java.lang.Object (जो) वांछित इंटरफ़ेस का विस्तार करता है, या यह "दृश्यों के पीछे" फ्रेमवर्क वर्ग के कुछ प्रकार को तत्काल बनाता है जो "कार्यान्वयन इंटरफ़ेस" खंड के साथ उत्पन्न हुआ था कक्षा परिभाषा में। इंटरफ़ेस में डिफ़ॉल्ट कन्स्ट्रक्टर नहीं है।

+0

मेरा मानना ​​है कि EasyMock CGLIB का उपयोग करता है। मॉकिटो CGLIB का उपयोग करता है। CGLIB एक लाइब्रेरी है जो आपको प्रॉक्सी ऑब्जेक्ट बनाने देती है। यह जावा प्रॉक्सी से तेज़ है क्योंकि यह बाइटकोड बनाता है/उसका उपयोग करता है। – mjlee

+0

EasyMock $ Proxy0 के समान नाम वाली कक्षा उत्पन्न करता प्रतीत होता है। $ चिह्न आमतौर पर एक आंतरिक/जेनरेट किए गए वर्ग के नाम का प्रतिनिधित्व करता है, और 0 संभवतः आंतरिक मॉक क्लास नंबर है जो EasyMock के आंतरिक आर्किटेक्चर के अनुसार है। इतना आसान तरीका अभी भी एक वर्ग बनाता है, इंटरफ़ेस नहीं; हालांकि, यह एक वर्ग बनाता है जो स्पष्ट रूप से इंटरफ़ेस लागू करता है। –

+0

यह उत्तर सिर्फ सादा बकवास है। जेवीएम पर वाइल्डकार्ड प्रकार हैं लेकिन वे कभी ठोस प्रकार का प्रतिनिधित्व नहीं करते हैं। कोई भी? -इंटर हमेशा एक ठोस प्रकार को संदर्भित करता है। –

7

मुझे सही दिशा देने के लिए अफफी के लिए धन्यवाद - मैं उसके उत्तर पर टिप्पणी करता हूं लेकिन फिर मैं समाधान को प्रारूपित करने में सक्षम नहीं होगा:

Annotation annotation = (Annotation) Proxy.newProxyInstance(
    clazz.getClassLoader(), 
    new Class[] { Annotation.class }, 
    new InvocationHandler() { 
    @Override public Object invoke(Object proxy, Method method, Object[] args) { 
     return clazz; // only getClass() or annotationType() should be called. 
    } 
    });
एक आकर्षण की तरह काम करता है।

+4

मैं यह नहीं समझ सकता कि क्या संभव है _good_ यह टूटा एनोटेशन उदाहरण आपको कर सकता है। ऐसा लगता है जैसे मैंने एक बर्गर के लिए पूछा और एक हैम सैंडविच की पुरानी काले और सफेद तस्वीर की एक फोटोकॉपी प्राप्त की। के बारे में बताएं? –

+0

मैं गुइस कोड के साथ काम कर रहा हूं जो बाध्यकारी एनोटेशन से संबंधित है। 'नामांकित' के अलावा, केवल 'एनोटेशन टाइप() 'और शायद' getClass()' को 'एनोटेशन' I पर कॉल किया जा रहा है जिसे मैं कॉल कर रहा हूं। इसलिए जब तक मेरी 'एनोटेशन' उन तरीकों की नकल कर सकती है, यह ठीक काम करेगी। – Steve

+0

@Steve 'getClass()' 'InvocationHandler' को पास नहीं किया जाएगा और' Proxy.class' देता है। लेकिन आप शायद डीबगर के लिए 'toString() 'चाहते हैं। – Brainlag

0

यदि आप संकलन समय पर एनोटेशन के प्रकार को जानते हैं, तो आप केवल एक कक्षा बना सकते हैं जो एनोटेशन लागू करता है जैसे कि यह एक सामान्य एनोटेशन था। this answer भी देखें।

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