2008-08-24 9 views
19

मैंने जावा फ़ंक्शन को परिभाषित किया है:मैं जेनेरिक जावा विधि में टाइप तर्क को स्पष्ट रूप से क्यों नहीं पारित कर सकता हूं?

static <T> List<T> createEmptyList() { 
    return new ArrayList<T>(); 
} 

इसे कॉल करने का एक तरीका ऐसा है:

List<Integer> myList = createEmptyList(); // Compiles 

मैं जेनेरिक प्रकार तर्क को स्पष्ट रूप से पारित करके इसे क्यों नहीं कह सकता? :

Object myObject = createEmtpyList<Integer>(); // Doesn't compile. Why? 

मुझे संकलक से त्रुटि Illegal start of expression मिलती है।

+1

Cheekysoft क्यों बताते हैं, लेकिन अगर आप वास्तव में जरूरत दूसरे प्रकार डीईएफ़ जोड़ने लग रहा है, बस से पहले स्थिर समारोह कॉल वर्ग के नाम जोड़ें: सूची MyList = MyClass। createEmptyList(); –

उत्तर

28

जब जावा कंपाइलर एक स्थिर विधि के लिए स्वयं पैरामीटर प्रकार का अनुमान नहीं लगा सकता है, तो आप इसे पूर्ण योग्य विधि नाम: कक्षा का उपयोग करके हमेशा पास कर सकते हैं। < टाइप> विधि();

Object list = Collections.<String> emptyList(); 
+6

पास न करें, गैर-स्थैतिक तरीकों के लिए आप इस कीवर्ड का उपयोग कर सकते हैं: ' ऑब्जेक्ट सूची = यह। खाली सूची(); ' – Roland

1

यह काफी कुछ समय के बाद से मैं जावा के उन हिस्सों में खोदे था, लेकिन ...

तुम क्यों नहीं कर सकते यह शायद भाषा डेवलपर्स द्वारा एक डिजाइन पसंद थे। फिर भी, जावा द्वारा नियोजित type erasure के कारण, जेनेरिक जानकारी किसी भी तरह संकलन समय पर गिरा दी जाती है, इसलिए आपके उदाहरण में यह वही बाइट कोड बनाएगा चाहे आपके पास टाइप पैरामीटर था या नहीं।

22

यदि आप विधि पैरामीटर के रूप में टाइप करते हैं तो आप कर सकते हैं।

static <T> List<T> createEmptyList(Class<T> type) { 
    return new ArrayList<T>(); 
} 

@Test 
public void createStringList() { 
    List<String> stringList = createEmptyList(String.class); 
} 

तरीके उसी तरह से genericised नहीं किया जा सकता है कि एक प्रकार कर सकते हैं, तो एक गतिशील टाइप सामान्य वापसी प्रकार के साथ एक विधि के लिए एकमात्र विकल्प - ओफ़्फ़ कि एक कौर :-) है - में पारित करने के लिए है एक तर्क के रूप में प्रकार।

जावा जेनरिक, see Angelika Langer's generics FAQ पर वास्तव में उत्कृष्ट पूछे जाने वाले प्रश्नों के लिए।


का पालन-अप:

इस संदर्भ Collection.toArray(T[]) में के रूप में सरणी तर्क का उपयोग करने के कोई मतलब नहीं होगा। एक सरणी का उपयोग करने का एकमात्र कारण यह है क्योंकि परिणाम (पूर्व-आवंटित) सरणी का उपयोग परिणामों को शामिल करने के लिए किया जाता है (यदि सरणी उन सभी में फिट करने के लिए पर्याप्त है)। यह हर समय रन-टाइम पर एक नई सरणी आवंटित करने पर बचाता है।

हालांकि, शिक्षा के प्रयोजनों के लिए, आप सरणी टाइपिंग उपयोग करने के लिए करना चाहता था अगर, वाक्य रचना बहुत समान है:

static <T> List<T> createEmptyList(T[] array) { 
    return new ArrayList<T>(); 
} 

@Test 
public void testThing() { 
    List<Integer> integerList = createEmptyList(new Integer[ 1 ]); 
} 
+1

-1 यह एक आम गलत धारणा है कि एक वर्ग शाब्दिक को सामान्य विधि में पारित करने की आवश्यकता होती है जब कोई अन्य तर्क संकलक को सामान्य प्रकार का अनुमान नहीं देता है। यह सब वास्तव में आवश्यक है [Xavier के उत्तर] में वर्णित वाक्यविन्यास (http://stackoverflow.com/a/25877)। वैसे भी, जैसा कि [हेनरिक का उत्तर] (http://stackoverflow.com/a/24996) उल्लेख करता है, किसी नए जेनेरिक ऑब्जेक्ट के प्रकार पैरामीटर निर्दिष्ट करने के लिए कोई वास्तविक उपयोग केस नहीं है जब इसे तुरंत एक चर के लिए असाइन किया जाता है - केवल प्रकार का तब से परिवर्तनीय समय संकलित समय पर भी। जावा 7 के '<>' वाक्यविन्यास के पीछे यही कारण है। –

+0

आप पैरामीटर 'टाइप' का उपयोग नहीं करते हैं, इसलिए इसे – newacct

0

@pauldoo हाँ, आप बिल्कुल सही हैं। यह जावा जेनेरिक इमो के साथ कमजोरियों में से एक है।

मैं चेकेसॉफ्ट की प्रतिक्रिया देता हूं कि मैं यह भी देखना चाहता हूं कि जावा लोगों द्वारा यह कैसे किया जाता है, जैसे टी [] AbstractCollection#toArray (टी [] ए)। मुझे लगता है कि Cheekysofts संस्करण बेहतर है, लेकिन जावा एक को परिचितता का लाभ है।

संपादित करें: जोड़ा गया लिंक। को पुनः संपादित करें: अतः :)


Cheekysoft पर अनुवर्ती पर एक बग मिला: ठीक है, के रूप में यह है कि इसी उदाहरण कुछ ऐसा दिखाई देगा किया जाना चाहिये किसी प्रकार की एक सूची है:

static <T> List<T> createEmptyList(List<T> a) { 
    return new ArrayList<T>(); 
} 

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

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

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