2009-09-03 12 views
7

ईजी स्ट्रिंग्स की एक ArrayList बनाने के लिए हम इतना है कि हम केवल टाइप करने के लिएजावा कन्स्ट्रक्टर के लिए टाइप अनुमान का समर्थन क्यों नहीं करता है?

List<String> list = new ArrayList(); 

है की तरह

List<String> list = new ArrayList<String>(); 

कुछ करने के लिए, जबकि यह निर्माता के लिए पैरामीटर प्रकार अनुमान लगाने के लिए सक्षम होना चाहिए है क्यों नहीं कर सकते हैं इस तरह के प्रकार को इन तरीकों से इनकार किया जा सकता है कि जेनेरिक तरीकों के लिए पैरामीटर टाइप किए जाते हैं।

+4

क्या यह पूछने का कोई उद्देश्य है कि "भाषा एक्स क्यों विशेषता नहीं कर सकता है"? जवाब आमतौर पर "क्योंकि यह डिजाइन नहीं किया गया था"। – skaffman

+1

क्यों! ओह क्यों! यह जावा में जेनेरिक कार्यान्वयन के बारे में मेरी सबसे बड़ी शिकायतों में से एक है। एक स्थिर फैक्ट्री विधि में कन्स्ट्रक्टर को लपेटने से टाइप अनुमान एक आकर्षण की तरह काम करता है, तो कन्स्ट्रक्टर के साथ क्यों नहीं! –

+0

@ स्काफमैन: सच है, लेकिन भ्रमित चीज यह है कि पैरामीटरयुक्त तरीकों के लिए टाइप अनुमान मौजूद है, इसलिए कार्यान्वयन के नियम और जटिलता पहले से मौजूद है। वस्तु प्रत्याशा के लिए बस नहीं! –

उत्तर

22

यह एक जावा 7 सुधार है जिसे डायमंड ऑपरेटर भी कहा जाता है। वाक्य रचना हो जाएगा:

List<String> strings = new ArrayList<>(); 

आधिकारिक प्रस्ताव, accepted for inclusion in Project CoinImproved Type Inference for Generic Instance Creation

Rémi Forax के अनुसार, परिवर्तन तेज भंडार में पहले से ही है।

+0

हालांकि यह जानना अच्छा है, यह सवाल का जवाब नहीं देता है कि वर्तमान संस्करण * इसका समर्थन क्यों नहीं करता है। –

+0

@ जोचिम सॉर: मैं एक निश्चित उत्तर क्यों नहीं दे सकता हूं, लेकिन डायमंड प्रस्ताव द्वारा संदर्भित बग रिपोर्ट पढ़ने से मैं देख सकता हूं कि जावा 5 टाइमफ्रेम में समाधान अच्छी तरह से समझ में नहीं आया था। बिल्ली, जेनेरिक जावा 5 में कन्स्ट्रक्टर अनुमान को दबाए बिना भी थोड़ा सा बोर्क किया जाता है। –

+3

@ जोचिम ... मुझे विश्वास है कि आप जिस वाक्यांश को खोज रहे हैं वह "डिजाइन निरीक्षण" है। –

2

यह हो सकता है और यह JDK7 में शामिल करने के लिए एक विशेषता है।

1

इस प्रकार का अनुमान लगाया जा सकता है, लेकिन लेखकों ने अभी फैसला किया है कि कुछ मामलों में टाइप अनुमान लगाने के लिए बेहतर नहीं है।

यदि आप जेवीएम पर टाइप अनुमान चाहते हैं, तो scala देखें।

+1

समस्या यह है कि कुछ प्रकार की अनुमान है! पैरामीटरयुक्त विधियों पर पैरामीटर टाइप करें बस ठीक है! ऑब्जेक्ट सृजन पर समान नियम क्यों लागू नहीं किए जा सकते हैं? –

6

जैसा कि अन्य ने कहा है, यह on the list for Java 7 है। हालांकि, मैं यह इंगित करना चाहता हूं कि Google Collections Library पहले से ही विभिन्न संग्रहों के लिए इसका समर्थन करता है, यदि आप स्थिर आयात का उपयोग करने में प्रसन्न हैं। उदाहरण के लिए, मैं अक्सर कोड जैसे लिखें:

List<String> list = newArrayList(); 

आपको बस स्थिर आयात और new और ArrayList() :)

के बीच की जगह को दूर (स्थिर आयात, btw Lists वर्ग के लिए किया जाएगा । नक्शे आदि)

+4

व्यक्तिगत रूप से मुझे लगता है कि यह बहुत बदसूरत है। :) – Bombe

+4

जब आप इसे पहली बार देखते हैं तो यह अजीब बात है, लेकिन जब आप इसका उपयोग करते हैं तो यह अव्यवस्था को काफी कम कर सकता है। –

+0

+1। मैं इन दिनों सोचने के बिना इसका उपयोग करता हूं, क्योंकि स्वत: पूर्ण होने पर ग्रहण आयात को सम्मिलित करेगा, और मेरे पास मेरे डिफ़ॉल्ट निर्माण पथ पर Google संग्रह हैं। – finnw

2

JDK7 सुविधाओं के अलावा, मैं तो तुम फैली और सुपर उपयोग कर सकते हैं अनुमान लगा रहा हूँ के लिए समान तरीके हैं।

class Animal {} 
class Dog extends Animal {} 

List<? extends Animal> anims = new ArrayList<Dog>(); 
List<? super Dog> superdogs = new ArrayList<Animal>(); 

आप इन दो मामलों में अनुमान लगाने में सक्षम नहीं होंगे।

+0

टाइप अनुमान केवल तभी उपयोग किया जाएगा यदि आपने इसे मैन्युअल रूप से निर्दिष्ट नहीं किया है (जैसा कि अभी यह टाइप किए गए तरीकों के साथ है), इसलिए यह असंभव नहीं होगा। –

2

आप चाहते हैं कि वर्तमान जावा इसका समर्थन न करे।

मैं केवल इतना कह सकता हूं कि जहां भी संभव हो जावा आमतौर पर कुछ कदम उठाता है। मुझे लगता है कि कुछ छोटी तकनीकी गड़बड़ी थी कि वे जावा 7 से पहले "दाएं" होने के बारे में निश्चित नहीं थे - शायद कुछ निश्चित होने के साथ कुछ करने के लिए यह कुछ पुराने या गैर-जेनेरिक कोड में अस्पष्ट मामला नहीं बनाएगा ।

सूचना कैसे रॉबर्ट ने बताया कि वाक्य रचना यह होगा:

List<String> strings = new ArrayList<>(); 

सूचना खाली <>? मुझे लगता है कि पुराने गैर-जेनेरिक कोड से इस तरह के अनुमान को असंबद्ध करना है; यह शायद कुछ ऐसा है जो उन्होंने पहले नहीं सोचा था।

+0

ये, मैंने अभी रॉबर्ट के लिंक पढ़े हैं और <> कच्चे प्रकार के गधे से अलग होना है जो आप कहते हैं। – Tarski

+0

दिलचस्प है कि इस प्रकार की विपरीत दिशा सी # में ली गई है जहां स्पष्ट प्रकार दाईं ओर है और इसके बजाय चर का प्रकार अनुमानित है। ध्यान दें कि सी # के कार्यान्वयन में यह आपको प्रकार को स्पष्ट रूप से परिभाषित किए बिना अन्य विधि कॉल से रिटर्न प्रकारों का अनुमान लगाने की अनुमति देता है। var तार = नया ArrayList (); मुझे इसे पहले जोड़ना है, मैंने सी # में var कीवर्ड की इतनी परवाह नहीं की है, लेकिन जितना अधिक मैं इसका उपयोग करता हूं और जेनरिक और गुमनाम प्रकारों के प्रकार के अनुमान के साथ यह सब बहुत ही मिलनसार बन जाता है। – jpierson

0

मैं कोई जावा सुपर-विशेषज्ञ नहीं हूं, इसलिए मैं पूरी तरह से सुनिश्चित नहीं हूं कि मैं क्या कहूंगा। यहां मेरे विचार हैं:

चूंकि जावा मिटिक्स द्वारा जेनेरिक लागू करता है, प्रत्येक सामान्य प्रकार के लिए एक अंतर्निहित कच्चा प्रकार होता है। यदि आप एक सामान्य प्रकार को परिभाषित करते हैं, तो एक अंतर्निहित कच्चा प्रकार होगा जो Object का उपयोग करेगा।

जब आप एक नया ArrayList का दृष्टांत, यह संकलक इन्स्टेन्शियशन वर्ग से प्रकार पैरामीटर अनुमान लगाने के लिए के लिए (अपने उदाहरण में ArrayList<String>) गलत होगा, के रूप में वहाँ है कि सही नाम और कोई प्रकार पैरामीटर के साथ एक वर्ग (जो है है कच्चा प्रकार, ArrayList)। मुझे यह भी लगता है कि यही कारण है कि जावा 7 में आपको कंपाइलर को प्रकार का अनुमान लगाने के लिए कन्स्ट्रक्टर कॉल में <> जोड़ना होगा।

कोई तर्क दे सकता है कि संकलक को केवल कच्चे प्रकार को तत्काल करना चाहिए जब परिभाषा वर्ग कच्चा प्रकार है, लेकिन मुझे लगता है कि यह भ्रमित होगा। मुझे लगता है कि संकलक को अपूर्ण अभिव्यक्तियों का अनुमान लगाना होगा जो किसी भी संदर्भ के साथ अमान्य होगा, जो new ArrayList() कथन के मामले में नहीं है।

मुझे उम्मीद है कि यह स्पष्ट है, और यदि मैं गलत हूं तो कोई मुझे सही कर सकता है।


साइड नोट:

इसके अलावा, सावधान रहना है कि कच्चे वर्ग प्रकार प्रकार पैरामीटर के रूप में Object का उपयोग कर के रूप में ही नहीं है:

List<String> list = new ArrayList(); 

, मान्य है जहां

List<String> list = new ArrayList<Object>(); 
के रूप में

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

+0

मुझे इस सवाल का जवाब देने जैसा लगा क्योंकि मुझे लगता है कि कोई जवाब नहीं है (जो सभी उत्कृष्ट हैं!) वास्तव में प्रारंभिक प्रश्न को संबोधित करते हैं जो * क्यों * है :) – Philippe

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