2012-11-18 17 views
5
interface A { 
    String n(); 
} 
class B implements A { 
    @Override 
    public String n() { return "asdf"; } 
} 
interface C<T extends A> { 
    T m(T t); 
} 
class D implements C<B> { 
    @Override 
    public B m(B b) { 
     return b; 
    } 
} 

Class<C<? extends A>> x = D.class; 

अंतिम पंक्तिइस प्रकार वाइल्डकार्ड क्यों काम नहीं करता है?

Type mismatch: cannot convert from Class<D> to Class<C<? extends A>> 

इस पूरी तरह से मेरे लिए ठीक लग रहा है पर कोई त्रुटि है, लेकिन शायद मैं कैसे प्रकार वाइल्डकार्ड काम पर कुछ सूक्ष्मता याद आ रही है। क्या कोई तरीका है कि मैं आखिरी पंक्ति पर प्रकार बदल सकता हूं? मैं इस संदर्भ की आवश्यकता क्योंकि मैं बाद में ऐसा करने पर योजना:

B b = new B(); 
A y = x.newInstance().m(b); 

यह भी

The method m(capture#1-of ? extends A) in the type C<capture#1-of ? extends A> is not applicable for the arguments (B) 

लेकिन कोई त्रुटि है तो अगर मैं यह वाइल्डकार्ड और कब्जा के बिना उपयोग करें, यह ठीक काम करता है:

A z = D.class.newInstance().m(b); 

दुर्भाग्यवश मैं अब इसके साथ फंस गया हूं, किसी भी मदद की सराहना की जाएगी।

संपादित करें: हटाया this. संदर्भ

संपादित: एक्स बदल

Class<? extends C<? extends A>> x = D.class; 

होने के लिए और यह काम करता है। हालांकि यह अभी भी पर त्रुटियों हो रही x.newInstance().m(b)

The method m(capture#2-of ? extends A) in the type Test.C<capture#2-of ? extends A> is not applicable for the arguments (B) 

उत्तर

6

ठीक है, अभी पिछले भाग पर ध्यान केंद्रित:।

लेकिन अभी भी x.newInstance पर त्रुटियों हो रही() मीटर (ख)

The method m(capture#2-of ? extends A) in the type 
Test.C<capture#2-of ? extends A is not applicable for the arguments (B) 

दरअसल - और यह सही समझ में आता है। क्योंकि आपके कोड में कुछ भी इंगित करता है कि आपको वास्तव में C<B> मिला है। सभी संकलक जानता है कि newInstanceकुछ प्रकार है जो लागू करता C<X> के लिए कुछ प्रकार X जो A लागू करता है का एक उदाहरण वापस आ गया है है। यह कैसे पता चलेगा कि यह B है?

आप m(b) कॉल करना चाहते हैं, तो आप एक C<B>, कि अपने घोषणा

Class<? extends C<B>> x = D.class; 

उस समय की आवश्यकता होगी, जिसका मतलब है, विधि मंगलाचरण सफाई से संकलित की आवश्यकता होगी। यह वास्तव में स्पष्ट नहीं है कि आप क्या हासिल करने की कोशिश कर रहे हैं, या यह आपके लिए पर्याप्त होगा या नहीं - लेकिन उम्मीद है कि यह आपको बता रहा है कि आपको क्यों त्रुटि मिल रही है ...

+0

'बी लागू नहीं करता है 'हालांकि? मेरे पास इस उदाहरण में 'बी' है, लेकिन मैं पुस्तकालय को 'ए' के ​​साथ काम करना चाहता हूं। पुस्तकालय एक वरीयता या विन्यास पुस्तकालय है। ए HasPreferences है, और सी serializeable वरीयता वर्ग है।तो सी के उप-वर्गों के साथ प्रत्येक के उपप्रकार होंगे अर्थात् सी – aepurniet

+0

सी के लिए वरीयता वस्तु है, ए को कॉन्फ़िगरेशन जानकारी को पकड़ने के लिए ए प्राप्त होगा। और उन पर कॉन्फ़िगरेशन भी लागू करेगा। ए के लिए कई सी हो सकते हैं (यही कारण है कि मैंने इसे अन्य तरीकों के बजाए इस तरह से टेम्पलेट किया है) – aepurniet

+0

@ एपर्नियट: 'बी' 'ए' लागू करता है, लेकिन 'सीएम' का पैरामीटर प्रकार का नहीं है 'ए' - यह प्रकार' टी' है। 'डी' 'ए' के कुछ अन्य कार्यान्वयन के नहीं,' बी' का उदाहरण प्राप्त करने पर भरोसा कर सकता है। यही कारण है कि यह एक समस्या पैदा कर रहा है। 'कक्षा <की घोषणा में कुछ भी नहीं है? सी > जो 'बी' का उल्लेख करता है ... –

0

इसके प्रकार असुरक्षित (मुझे लगता है , एनोटेशन प्रदूषण से बचने के लिए उन चेतावनियों को बंद कर दिया गया है)

Class<? extends C> x = D.class; 
    B b = new B(); 
    A y = x.newInstance().m(b); 
    A z = D.class.newInstance().m(b); 

लेकिन यह काम करता है।

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