2010-10-26 27 views
5

यहाँ से अलग कुछ कोड मैं पर काम कर रहा हूँ का एक उदाहरण है:जावा जेनेरिक्स अपेक्षित वापसी प्रकार वास्तविक

public interface FooMaker<T extends Enum<T> & FooType> 
{ 
     public List<Foo<T>> getFoos(String bar); 
} 

आइए आगे मान लेते हैं कि FooMaker के कई अलग अलग ठोस कार्यान्वयन किया जाएगा। तो मैंने FooMakers का उपयोग करने के लिए कुछ कोड लिखा था।

FooMaker<?> maker = Foos.getRandomMaker(); 
List<Foo<?>> fooList = maker.getFoos("bar"); //error here! 

कोड की दूसरी पंक्ति समस्या होती है, ग्रहण मुझसे कहता कोड होना चाहिए:

FooMaker<?> maker = Foos.getRandomMaker(); 
List<?> fooList = maker.getFoos("bar"); 

मैं मुसीबत समझ क्यों सूची में पैरामिट्रीकृत प्रकार के रूप में फू घोषणा जाना पड़ता है हो रही है वापसी प्रकार सही करने के लिए दूर।

कोई विचार?

+0

'टी 0 एन37 और फ़ूटाइप' क्या होगा? टी को एक enum होना और FooType का विस्तार करना है, लेकिन आप एक enum विस्तार नहीं कर सकते हैं! –

+0

जेनरिक के साथ, कीवर्ड "विस्तार" का उपयोग कार्यान्वित इंटरफेस का वर्णन करने के लिए किया जाता है। FooType भी एक इंटरफ़ेस है और आप अभी भी विस्तारित कीवर्ड का उपयोग करेंगे। – Nick

उत्तर

1

बजाय इस प्रयास करें:

List<? extends Foo<? extends Enum<?>>> fooList = maker.getFoos("bar"); 

समस्या यह है कि अगर यह अनुमति दी गई है:

List<Foo<?>> fooList = maker.getFoos("bar"); 

फिर विस्तार से, जहां आप जा चुके हैं इसके साथ भी दूर जाने में सक्षम:

Foo<?> foo1 = new Foo<String>(); 
Foo<?> foo2 = new Foo<Integer>(); 
fooList.add(foo1); 
fooList.add(foo2); 

जो लौटाई गई सूची के सामान्य अनुबंध को अमान्य कर देगा।

इसे रोकने के लिए, जावा कंपाइलर रिटर्न प्रकार को वाइल्डकार्ड-आधारित होने के लिए मजबूर करता है, जिसका अर्थ है कि फू को रिटर्न-टाइप (सूची से तत्वों को खींचने के लिए) के रूप में उपयोग किया जा सकता है लेकिन आप वाइल्डकार्ड- आपकी सूची में आधारित फू प्रकार।

+0

यह वास्तव में सही मायने रखता है। अमान्यता वह जगह है जहां सबकुछ बेकार हो जाता है। आपका सुझाव विज्ञापित के रूप में काम करता है। मदद के लिए धन्यवाद। – Nick

0

क्योंकि आप maker को FooMaker<?> के रूप में घोषित कर रहे हैं। यदि आप जानते हैं कि TAwesomeFooMaker रिटर्न क्या है तो आप इसे AwesomeFooMaker के प्रकार के रूप में क्यों घोषित नहीं करेंगे?

+0

मैं अपना कोड एक स्मीज संपादित करूंगा। मैं वास्तव में नहीं जानता कि मुझे कौन सा फूमेकर मिल रहा है। – Nick

+2

यह वास्तव में कोई फर्क नहीं पड़ता। प्रकार पैरामीटर को '?' के रूप में घोषित करके आप बता रहे हैं "मुझे नहीं पता कि यह किस प्रकार वापस आएगा 'और संकलक अनिवार्य रूप से कार्य करता है जैसे टाइप पैरामीटर से संबंधित कोई भी विधि अब'? 'है, भले ही यह' सूची ' क्या आप 'FooMaker <' का उपयोग नहीं कर सकते हैं? FooType> maker' को बढ़ाता है? –

+0

इंटरफ़ेस का रिटर्न प्रकार सूची > है, मेरी घोषणा के साथ मैं कह रहा हूं कि यह किसी भी प्रकार का टी हो सकता है। भले ही मैं FooMaker घोषित करता हूं निर्माता, मुझे अभी भी एक ही त्रुटि मिल रही है। मैं समझने की कोशिश कर रहा हूं कि क्यों फू पैरामीटर प्रकार को अनदेखा किया जा रहा है। – Nick

1

सामान्य:

class Bar {} 
class Baz {} 

FooMaker<?> maker = new FooMaker<Bar>(); 
List<Foo<?>> fooList = maker.getFoos("bar"); //error here! 
fooList.add(new Foo<Baz>());     //cock-up here! 
+0

मैंने दूसरे व्यक्ति को प्रश्न का उत्तर देने के रूप में चुना क्योंकि उसने मेरी सीमाओं के आसपास काम करने का एक तरीका शामिल किया था, लेकिन मैं आपके इनपुट की सराहना करता हूं जैसा कि मैंने उम्मीद की थी, यह क्यों काम नहीं करता है। +1 – Nick

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