2013-02-16 10 views
12

List<String> list = new ArrayList(); परिणामस्वरूप संकलक चेतावनी होगी।जावा 7 में टाइप अनुमान के लिए हीरा ऑपरेटर का उपयोग क्यों किया जाता है?

हालांकि निम्न उदाहरण किसी चेतावनी के बिना संकलित: List<String> list = new ArrayList<>();

मैं उत्सुक क्यों हीरा ऑपरेटर के शुरू में सभी की जरूरत है हूँ। यदि प्रकार तर्क अनुपस्थित है क्यों न सिर्फ निर्माता पर प्रकार निष्कर्ष है (के रूप में अपनी पहले से ही जावा में स्थिर तरीकों के लिए किया जाता है और गूगल अमरूद की तरह संग्रह पुस्तकालयों द्वारा शोषण)

संपादित: मैं देखा प्रारंभिक बिंदु के रूप millimoose उत्तर का उपयोग करना वास्तव में किस तरह का मिटा है और यह सिर्फ सभी प्रकार की जानकारी को हटा नहीं रहा है। संकलक वास्तव में थोड़ा अधिक (official doc से नकल) करता है:

  • उनकी सीमा के साथ सामान्य प्रकार के सभी प्रकार पैरामीटर बदलें या वस्तु यदि प्रकार पैरामीटर असीम हैं। उत्पादित बाइटकोड, इसलिए, केवल सामान्य वर्ग, इंटरफेस, और विधियों में शामिल हैं।
  • प्रकार सुरक्षा को संरक्षित रखने के लिए आवश्यक प्रकार डालें।
  • विस्तारित जेनेरिक प्रकारों में बहुरूपता को संरक्षित करने के लिए पुल विधियों को उत्पन्न करें।
+7

मैं इसे कच्चे प्रकार, जो संकलक बनाने का उपयोग करने से यह भेद करने के लिए है यह सोचते हैं रहा हूँ कुछ करना संगतता के लिए पूरी तरह से अलग। (इसमें एक कच्चे प्रकार के साथ एक अभिव्यक्ति को जेनेरिक शामिल करने वाले व्यक्ति से भिन्न रूप से संसाधित किया जाता है।) – millimoose

+0

मैं शायद मिलीमोज़ से सहमत हूं, लेकिन यह देखते हुए कि जनरेटर को संकलक के दौरान मिटा दिया जाता है जो संकलक चेतावनी की पिछड़े संगतता के लिए नए ऑपरेटर ('केवल') पेश करता है सही महसूस नहीं करता है। –

+0

पीछे की संगतता कंपाइलर चेतावनियों के लिए नहीं है। 'ऑब्जेक्ट एस = नया ऐरेलिस्ट()। (प्राप्त करें) जैसे स्टेटमेंट में' स्ट्रिंग एस = नया ऐरेलिस्ट () .get कहने के बजाय दाएं हाथ के पक्ष का परिणाम अलग-अलग हल किया गया है (पूर्व-जेनेरिक एल्गोरिदम का उपयोग करके)() '। यह तब भी लागू होता है जब आप 'इंटररेलिस्ट' को मध्यवर्ती चर में संग्रहीत करते हैं। – millimoose

उत्तर

8

निश्चित उत्तर किसी ऐसे व्यक्ति से आना होगा जिसने उस सुविधा को डिजाइन किया है, लेकिन मुझे लगता है कि इसे कच्चे प्रकारों का उपयोग करने से अलग करना है, जिससे संकलक संगतता के लिए पूरी तरह से कुछ अलग करता है। Generic screws up non-related collection

+0

+1 –

+0

@ फिलिपवेन्डलर हाल ही की स्मृति में यह प्रश्न वास्तव में मुझे इस उत्तर में ले जाता है, इसलिए क्रेडिट का हिस्सा भी इसके लेखक के पास जाता है। – millimoose

3

यह जावा 7.
में Java Generics में एक सुधार का हिस्सा है इससे पहले कि आप

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

अब लिखने के लिए आपको

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

कौन सा बराबर है लिख सकते हैं पड़ता था - कंपाइलर आपके लिए काम करेगा। इस रूप में

final List list = new ArrayList(); 

कौन सा एक untyped List है समान नहीं है।

7

जावा डेवलपर्स मौजूदा कार्यक्रमों के व्यवहार को बदलने से बचने के लिए बहुत मेहनत करते हैं। List<String> list = new ArrayList(); संकलित करता है, और एक कच्चे ArrayList बनाता है। यदि टाइप अनुमान इसे लागू किया गया तो परिणाम ArrayList<String> होगा, जो इसके व्यवहार को बदल रहा है और संभवतया प्रोग्राम में कहीं और रन टाइम त्रुटियों का कारण बनता है।

============================================== =======================12=======

आगे विचार करने के बाद, और @ मिलिमोस द्वारा एक टिप्पणी, मैं देखता हूं कि परिवर्तन व्यवहार में प्रारंभकर्ता के लिए स्थानीय होगा, और संकलन समय पर पता चला। निम्नलिखित कार्यक्रम पर विचार करें:

import java.util.ArrayList; 
import java.util.List; 


public class Test { 
    public static void main(String[] args) throws Exception { 
    List<Integer> integers = new ArrayList<Integer>(); 
    integers.add(Integer.valueOf(3)); 
    integers.add(Integer.valueOf(4)); 
    List<String> list = new ArrayList(integers); 
    System.out.println(list); 
    } 
} 

बिना प्रकार निष्कर्ष है, यह चलता है और प्रिंट [3, 4], एक List<String> कि पूर्णांक संदर्भ शामिल हैं की अवांछनीय स्थिति के बावजूद।

टाइप अनुमान के साथ, यह संकलित नहीं होगा क्योंकि ArrayList(Collection<? extends E> c) के उपयोग को ArrayList<String> बनाते समय तर्क के रूप में उपयोग करने की अनुमति नहीं देता है।

+0

@millimoose इसके बारे में सोचने के बाद, मैं सहमत हूं। व्यवहार में परिवर्तन प्रारंभकर्ता के लिए स्थानीय होंगे, और संकलन समय पर पता चला है। मैं एक उदाहरण दिखाने के लिए अपना जवाब संपादित करूंगा।जेनिक्स और कच्चे प्रकार के बीच अंतर का उदाहरण देने के लिए –

4

पूरा वाक्य रचना जावा 5 और 6 के संकलक के लिए आवश्यक है:

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

वे हमारे लिए वाक्य रचना को सरल बनाने और असाइनमेंट ऑपरेटर के दोनों किनारों पर एक ही प्रकार के मापदंडों लिखने के लिए नहीं की अनुमति देने का फैसला किया। हालांकि <> ऑपरेटर को यह सुनिश्चित करने के लिए अभी भी आवश्यक है कि आप समझें कि आप क्या कर रहे हैं। new ArrayList<>() लिखकर आप कहते हैं, "मैं समझता हूं कि मैं सामान्य प्रकार का उदाहरण बना रहा हूं और जेनेरिक पैरामीटर असाइनमेंट के बाईं तरफ घोषित किया गया है।"

1

दिलचस्प मामलों में जहां हीरे के साथ और एक rawtype के रूप में निर्माता बुला कर रहे हैं: उस में एक कच्चे प्रकार के साथ एक अभिव्यक्ति संसाधित किया जाता है आसानी से अलग ढंग से एक है कि जेनरिक शामिल है, एक उदाहरण यह तो सवाल में पाया जाता है की तुलना में सफलतापूर्वक संकलित करता है लेकिन विभिन्न कोड उत्पन्न करता है। विधि ओवरलोडिंग सुविधा के साथ मिश्रित होने पर ऐसे उदाहरण संभव हैं। आईआईआरसी, ओपनजेडीके सिक्का मेलिंग सूची पर कहीं भी एक उदाहरण था (नहीं, मैं इसे खोजने की कोशिश नहीं कर रहा हूं)।

जावा एसई 6 और जावा एसई 7 पर सफलतापूर्वक एक ही कोड सफलतापूर्वक आने के लिए स्वीकार्य नहीं था लेकिन विभिन्न परिणाम उत्पन्न करते थे।

मेरे पैसे के लिए, मैंने हीरे को छोड़ दिया होगा और एक चेतावनी दी होगी (एक त्रुटि के रूप में व्यवहार करें) यदि 7 में चुने गए अनुमान एल्गोरिदम द्वारा अलग कोड उत्पन्न किया गया था (अनिवार्य रूप से विधि जेनेरिक-प्रकार अनुमान के लिए जे 2 एसई 5.0)। यदि आपने ऐसा कोड लिखा है, तो यह संभवतः काम करने के लिए स्पष्ट नहीं है अगर यह संकलित है या नहीं।

0

यदि आपकी परियोजना मेवेन पर बनाई गई है, तो नीचे टैग के तहत pom.xml में जोड़ें। यह पूरी तरह से काम करता है .. <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins>

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