2011-12-20 12 views
9

मैं बस कुछ ऐसा चला गया जो मुझे समझ में नहीं आया। दूसरा लूप कानूनी के नीचे क्यों नहीं है जब दूसरा समान रूप से एक है?जावा जेनरिक और रिटर्न प्रकार

public interface SomeInterface<T> { 
    List<SomeNamedObject> getObjects(); 
    void doSomething(P1 p1, T p2); 
} 

public class SomeNamedObject { 
    private String text; 
} 

public class Clazz { 

    private SomeInterface someInterface; 

    ... 

    public void someMethod() { 
     // Error Type mismatch: cannot convert from element type Object to TestClass.SomeNamedObject 
     for (SomeNamedObject someNamedObject : someInterface.getObjects()) { 
      // This loop won't compile as the someInterface.getObjects returns just a List and not a List<SomeNamedObject> 
     } 

     // Warning Type safety: The expression of type List needs unchecked 
     // conversion to conform to List<TestClass.SomeNamedObject> 
     List<SomeNamedObject> objects = someInterface.getObjects(); 
     for (SomeNamedObject someNamedObject : objects) { 
      // This loop compiles 
     } 
    } 
} 
+0

कोई बग नहीं, यह मिटाने और कच्चे प्रकार के साथ एक समस्या है। – Stefan

+0

मुझे नहीं पता कि समस्या क्या हो सकती है। क्या आप वास्तविक स्टैक ट्रेस पोस्ट कर सकते हैं (केवल पहली कुछ पंक्तियां)। मुझे लगता है कि आपकी पूर्ण कक्षा को "कुछ इंटरफेस " की आवश्यकता है, लेकिन उदाहरण के लिए "" की आवश्यकता नहीं है, शायद वहां कुछ है? – Jay

+1

@Jay कुछ इंटरफेस की घोषणा ने सामान्य प्रकार निर्दिष्ट नहीं किया है, जावा फिर कच्चे प्रकार पर वापस आ जाता है और कच्चे सूची को वापस करने के लिए विधि हस्ताक्षर परिवर्तन (उत्तरों देखें)। उसे ऑब्जेक्ट असाइनमेंट पर चेतावनी का उल्लेख करना चाहिए था। – Stefan

उत्तर

18

क्योंकि आपके उदाहरण चर private SomeInterface someInterface इसके जेनेरिक प्रकार पैरामीटर निर्दिष्ट नहीं करता तो जेनरिक के सभी उपयोग someInterface लिए अक्षम है। इसका मतलब है कि someInterface.getObjects() में List<SomeNamedObject> की बजाय कच्चे रिटर्न प्रकार List है। यही कारण है कि पहला उदाहरण संकलित नहीं करता है।

दूसरे उदाहरण में List<SomeNamedObject> objects = someInterface.getObjects() सूची के लिए एक स्पष्ट प्रकार में डाल रहा है। जब आप ऐसा करते हैं तो आपको एक चेतावनी दिखाई देगी, हालांकि टाइप सुरक्षा की गारंटी नहीं है। यह वही व्यवहार है जो आप देखेंगे कि getObjects() को प्रकार पैरामीटर के बिना List getObjects() के रूप में परिभाषित किया गया था।

+0

यह मूल में एक टाइपो हो सकता है, लेकिन 'SomeInterface ' 'T' का उपयोग नहीं किया जाता है ताकि 'सूची' लौटने के लिए सामान्य प्रकार निर्दिष्ट किया जा सके, जिसे 'SomeNamedObject' के रूप में हार्ड कोड किया गया है। इसलिए, भले ही इंस्टेंस वैरिएबल टाइप नहीं किया गया हो, फिर भी इसे वापस 'सूची' को प्रभावित नहीं करना चाहिए। –

+5

यदि जेनेरिक पैरामीटर 'कुछ इंटरफेस' की घोषणा में निर्दिष्ट नहीं है तो * कुछ * इंटरफेस 'में * सभी * जेनेरिक प्रकारों को अनदेखा/अक्षम कर दिया जाता है, भले ही वे 'टी' पर निर्भर न हों। – mikej

+0

बहुत दिलचस्प, हालांकि अनोखा। –

3

आपको ध्यान रखना चाहिए कि जब आप दूसरी लूप से पहले ऑब्जेक्ट्स को इंगित करते हैं तो आपको एक कंपाइलर चेतावनी मिलती है।

Type safety: The expression of type List needs unchecked conversion to conform to 
List<TestClass.SomeNamedObject> 

यह आपको बताया है कि किसी कारण से आपका getObjects() विधि एक गैर generified सूची लौटा रहा है होगा। जो बताता है कि पहला पाश संकलित क्यों नहीं करता है।

क्योंकि आप अपने संदर्भ generify करना भूल गया:

private SomeInterface someInterface; 

आप न generify यह सब कुछ घोषित विधि के हस्ताक्षर सहित, कच्चे प्रकार का उपयोग करेगा। यह एक कच्चे सूची वस्तु के बजाय रिटर्न एक सूची <SomeNamedObject> की तरह

private SomeInterface<Object> someInterface; 

कुछ करो और यह काम करना चाहिए मतलब है।

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