2012-05-09 15 views
11

मैं एक सार जावा वर्ग में निम्न कोड की है। लेकिन अगर मैं इसे कहीं भी कहते हैं, संकलक शिकायत:जावा: पॉलिमॉर्फिक रिटर्न टाइप एक सार विधि में?</p> <pre><code>protected abstract <E extends HasText & IsWidget> E createNewDisplayWidget(); </code></pre> <p>कौन सा ठीक संकलित:

Bound mismatch: The generic method createNewDisplayWidget() of type DemoClass is not applicable for the arguments(). The inferred type HasText is not a valid substitute for the bounded parameter <E extends HasText & IsWidget> 

वहाँ कुछ है कि कई इंटरफेस को लागू करना चाहिए वापस जाने के लिए एक सार विधि की आवश्यकता के लिए एक रास्ता है?

नोट: नहीं, मैं एक विशेष इंटरफ़ेस नहीं बना सकता जो मुझे पसंद है। जीडब्ल्यूटी में लेबल जैसे विजेट हैं जो पहले ही इंटरफेस को लागू करते हैं और मैं विजेट का उपयोग करना चाहता हूं।

संपादित करें:

http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

+0

क्या आपने एक के बजाय कॉमा के साथ प्रयास किया है? – sp00m

+0

एक कॉमा का मतलब यह होगा कि IsWidget पर बाध्य समाप्त होता है। हैस्टक्स्ट को फिर अनदेखा कर दिया जाता है। कंपाइलर एक चेतावनी फेंकता है कि दूसरा प्रकार 'छुपा' है। – McTrafik

+4

क्या आप हमें अपनी एक/कुछ कॉल साइट दिखा सकते हैं? –

उत्तर

2

समस्या ग्रहण में थी। मैंने 3.7 से 3.7.2 तक अपग्रेड किया और संकलक त्रुटि दूर चली गई।

मुझे यह नहीं पता कि इसका क्या प्रभाव है। अगर किसी के पास कोई सुराग है तो कृपया मेरा उत्तर अपडेट करने में संकोच न करें।

+0

हां, यह समझ में आता है। [ग्रहण 3.7.1 के रिलीज नोट्स] (http://www.eclipse.org/eclipse/development/readme_eclipse_3.7.1.html#DefectsFixed) निश्चित [बग 341795] सूचीबद्ध करता है (https://bugs.eclipse.org /bugs/show_bug.cgi?id=341795), जो उसी स्थिति का वर्णन करता है, जिसमें आपने वास्तव में त्रुटि संदेश देखा था! –

2

मैं अपने प्रश्न के आधार पर एक कोशिश दे दिया है और मैं एक त्रुटि के बिना के माध्यम से प्राप्त करने में सक्षम था: मैं विचार यहां से यह करने के लिए मिल गया (पेज 22) । कृपया मेरे द्वारा बनाए गए वर्गों की जांच करें।

TestClass

public abstract class TestClass { 

    protected abstract <E extends HasText & IsWidget > E createNewDisplayWidget(); 

} 

HasText वर्ग

public class HasText { 

} 

IsWidget

public interface IsWidget { 

} 

DemoClass

public class DemoClass extends HasText implements IsWidget{ 

    } 

TestClass1

public class TestClass1 extends TestClass{ 

    @Override 
    protected DemoClass createNewDisplayWidget() { 
     // TODO Auto-generated method stub 
     DemoClass type = new DemoClass(); 
     return type; 
    } 

    public void checkOut(){ 
     if(createNewDisplayWidget() instanceof HasText || createNewDisplayWidget() instanceof IsWidget){ 
      System.out.println("Yes it works"); 
     } 
     else{ 
      System.out.println("It doesnt"); 
     } 
    } 

    public static void main(String[] args){ 
     TestClass1 check = new TestClass1(); 
     check.checkOut(); 

    } 

} 

जब मैं अपने मुख्य कार्यक्रम चलाने मैं हमेशा मिलता है "हाँ, यह काम करता है"। कृपया मुझे बताएं कि मुझे कुछ याद आ रहा है।

+0

आप उसी कक्षा से 'createNewDisplayWidget()' को कॉल कर रहे हैं जहां आपने इसे एक अधिक ठोस रिटर्न प्रकार दिया था। मैंने इसे 'डेमो क्लास' से कॉल करने का प्रयास किया लेकिन ओपी की त्रुटि को पुन: उत्पन्न नहीं कर सका। शायद यह एक जीडब्ल्यूटी-विशिष्ट समस्या है। – mpartel

+0

हां। जिस समस्या को मैं चारों ओर घूमने की कोशिश कर रहा था उसे "डेमो क्लास" जैसे किसी अन्य प्रकार का निर्माण नहीं करना था। यह वास्तव में मैं जिस समाधान के साथ गया था, लेकिन यह वह नहीं है जिसे मैं ढूंढ रहा था क्योंकि अब मुझे जीडब्ल्यूटी से प्रत्येक कक्षा के लिए कस्टम प्रकार बनाना है, जिसका उपयोग करना चाहता था। – McTrafik

0

आप क्या करना चाहते हैं, अगर जावा सीधे अवरोधन प्रकार का समर्थन करता ही संभव है तो आप कर सकते हैं बस

HasText&IsWidget createNewDisplayWidget(); 

किसी भी कार्यान्वयन एक वस्तु प्रकार HasText&IsWidget की एक उप-प्रकार है कि लौटना चाहिए; दूसरे शब्द में, लौटाया गया प्रकार HasText और IsWidget

दुर्भाग्यवश, जावा इसका समर्थन नहीं करता है।

अपने प्रयास किया समाधान की समस्या दो कोणों से समझा जा सकता है:

1) एक प्रकार चर पर कमी कर रहे हैं फोन करने वाले पर कमी; कॉलर वास्तविक प्रकार तर्क प्रदान करता है, और इसे बाधाओं को पूरा करना होगा। आप वास्तव में क्या चाहते हैं कैली पर बाधाएं हैं।

2) यदि एक प्रकार चर केवल वापसी प्रकार में दिखाई देता है, लेकिन विधि पैरामीटर के प्रकार नहीं है, तो यह आमतौर पर समस्या का संकेत है।जावा में, बुराई टाइप एरर टाइप करें, विधि निकाय रनटाइम प्रकार तर्क को नहीं जान सकता है, इसलिए यह null जैसे कुछ छोटे मूल्यों को छोड़कर, कॉलर द्वारा वांछित उचित प्रकार का मान वापस नहीं कर सकता है; तुच्छ वापसी मान का एक और क्लासिक उदाहरण

java.util.Collections 
    <T> Set<T> emptySet() 
+0

उत्तर सही नहीं है, और आपको इसे स्वीकार नहीं करना चाहिए। सही क्या है, कि एक विधि हस्ताक्षर * एक समस्या का संकेत हो सकता है। लेकिन एक कारखाने के लिए जो उपप्रकारों का एक निश्चित सेट बनाता है, यह ठीक हो सकता है (सुविधा के लिए), और यह जावा में काम करता है (अगर आपको पसंद है तो बस @ @SuppressWarnings ("अनचेक") जोड़ें। आप Runtime पर ClassCastExceptions प्राप्त कर सकते हैं, और यह हमेशा सबसे अच्छा दृष्टिकोण नहीं हो सकता है, लेकिन ** यह आपको प्राप्त होने वाली कंपाइलर त्रुटि की व्याख्या नहीं करता है! –

+0

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

1

तो मैं त्रुटि उत्पन्न करने के लिए पूरा कोड कर की कोशिश की है, लेकिन किसी कारण से यह एक त्रुटि नहीं दिया। इसे थोड़ा सा देखें:

import java.util.LinkedList; 

public abstract class DemoClass { 

    public static void main(String[] args) { 
     DemoClass dc = new DemoClassImpl(); 
     dc.createNewLivingAndDying().live(); 
     dc.killAll(); 
    } 

    LinkedList<Dies> dying = new LinkedList<Dies>(); 

    public Lives createNewLivingAndDying() { 
     Lives ab = newLivingAndDying(); // This is where I expected an error 
     dying.add((Dies) ab); 
     return ab; 
    } 

    public void killAll() { 
     for (Dies dead : dying) 
      dead.die(); 
    } 

    protected abstract <E extends Lives & Dies> E newLivingAndDying(); 

} 

class DemoClassImpl extends DemoClass { 

    @SuppressWarnings("unchecked") 
    @Override 
    protected <E extends Lives & Dies> E newLivingAndDying() { 
     return (E) new SomePrivateClass(); // This is what I don't understand 
    } 

} 

interface Lives { 
    public void live(); 
}; 

interface Dies { 
    public void die(); 
}; 

class SomePrivateClass implements Lives, Dies { 

    @Override 
    public void die() { 
     System.out.println("Object Dies"); 
    } 

    @Override 
    public void live() { 
     System.out.println("Object Lives"); 
    } 
} 

यह कोड मेरे घर कंप्यूटर पर संकलित और चलाता है लेकिन मेरे काम कंप्यूटर पर त्रुटि प्रदान करता है।

Bound mismatch: The generic method newLivingAndDying() of type DemoClass is not applicable for the arguments(). The inferred type Lives is not a valid substitute for the bounded parameter <E extends Lives & Dies> 

इस बिंदु पर मुझे लगता है कि यह एक परियोजना सेटअप मुद्दा है लेकिन मुझे नहीं पता कि यह क्या है। जेआरई 1.6 दोनों।

+0

दूसरे शब्दों में , आप टाइप ऑब्जेक्ट के रूप में 'ऑब्जेक्ट' (निहित रूप से) का उपयोग कर त्रुटि को बाईपास करते हैं और उसके बाद किसी एक इंटरफ़ेस को कास्टिंग करते हैं। अगर आपको केवल 'लाइव्स' की आवश्यकता होती है, तो अलग-अलग रखें, 'लाइव्स लाइफ = न्यू लिविंग एंड डाइंग()' संकलित करने में विफल रहेगी, लेकिन 'जीवन रहता है = (जीवन) यह। newLivingAndDying() 'संकलित करेगा (और काम!) –

+0

@ थॉमसब्रायर' नया लिविंग एंडडिइंग() 'संकलित नहीं होगा :) कारण' ऑब्जेक्ट एबी = न्यू लिविंग एंड डाइंग(); 'संकलन जटिल है, तर्कसंगत रूप से प्रकार अनुमान में quirks के कारण । – irreputable

+0

@McTrafik, कास्टिंग करके, एक कार्यान्वयन घोषित रिटर्न प्रकार के बावजूद कुछ भी वापस कर सकता है। यह ठीक है, लेकिन आप कंपाइलर प्रकार की जांच खो देते हैं। आप 'ऑब्जेक्ट न्यू लिविंग एंड डाइंग() 'घोषित कर सकते हैं। – irreputable