java - * प्रकार से पहले रखे जाने पर निर्माण प्रकार के तर्कों का क्या अर्थ है?




generics syntax (2)

जेनेरिक कंस्ट्रक्टर को कॉल करना

यह असामान्य ठीक है, लेकिन पूरी तरह से वैध जावा है। समझने के लिए हमें यह जानना होगा कि एक कक्षा में एक सामान्य रचनाकार हो सकता है, उदाहरण के लिए:

public class TypeWithGenericConstructor {

    public <T> TypeWithGenericConstructor(T arg) {
        // TODO Auto-generated constructor stub
    }

}

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

    new TypeWithGenericConstructor(LocalDate.now(ZoneId.systemDefault()));

अब T स्पष्ट रूप से LocalDate । हालांकि ऐसे मामले भी हो सकते हैं जहां जावा प्रकार तर्क को कम (घटा) नहीं सकता है। फिर हम आपके प्रश्न से वाक्य रचना का उपयोग करके स्पष्ट रूप से इसकी आपूर्ति करते हैं:

    new <LocalDate>TypeWithGenericConstructor(null);

बेशक हम इसकी आपूर्ति भी कर सकते हैं भले ही यह आवश्यक न हो अगर हमें लगता है कि यह पठनीयता में मदद करता है या जो भी कारण हो:

    new <LocalDate>TypeWithGenericConstructor(LocalDate.now(ZoneId.systemDefault()));

अपने प्रश्न में आप java.util.ArrayList कंस्ट्रक्टर को कॉल करते दिख रहे हैं। वह कंस्ट्रक्टर जेनेरिक नहीं है (केवल ArrayList वर्ग एक पूरे के रूप में, वह कुछ और है)। जब आप उपयोग नहीं किए जाते हैं, तो जावा आपको कॉल में टाइप तर्कों की आपूर्ति करने की अनुमति देता है, नीचे मेरा संपादन देखें। मेरा ग्रहण मुझे एक चेतावनी देता है:

गैर-सामान्य निर्माता ArrayList () प्रकार ArrayList के लिए अप्रयुक्त प्रकार के तर्क; इसे तर्कों के साथ मानकीकृत नहीं किया जाना चाहिए

लेकिन यह एक त्रुटि नहीं है, और कार्यक्रम ठीक चलता है (मैं इसके अलावा List और ArrayList लिए लापता प्रकार के तर्क के बारे में चेतावनी प्राप्त करता हूं, लेकिन फिर से एक अलग कहानी है)।

सामान्य वर्ग बनाम जेनेरिक कंस्ट्रक्टर

क्या टाइप आर्ग्युमेंट्स की पोजिशनिंग का वही मतलब है जो उन्हें टाइप करने के बाद डालते हैं? यदि नहीं, तो अलग स्थिति का क्या मतलब है?

नहीं, यह अलग है। सामान्य प्रकार के तर्क / प्रकार ( ArrayList<Integer>() ) जेनेरिक वर्ग के लिए हैं निर्माणकर्ता के लिए पहले प्रकार के तर्क।

दो रूपों को भी जोड़ा जा सकता है:

    List<Integer> list = new <String, Long>ArrayList<Integer>();

मैं इसे थोड़ा और सही मानूंगा क्योंकि अब हम देख सकते हैं कि सूची में Integer ऑब्जेक्ट्स (मैं अभी भी व्यर्थ छोड़ना पसंद करूंगा <String, Long> , of course)।

जब ArrayList में केवल 1 हो तो 2 प्रकार के तर्क देना कानूनी क्यों है?

सबसे पहले, यदि आप टाइप करने से पहले टाइप तर्क वितर्क करते हैं, तो आपको क्लास के लिए नहीं, कंस्ट्रक्टर के लिए सही संख्या की आपूर्ति करनी चाहिए, इसलिए यह करने के लिए कुछ भी नहीं मिला है कि ArrayList वर्ग को कितने प्रकार के तर्क मिले हैं। इसका वास्तव में मतलब यह है कि इस मामले में आपको कोई भी आपूर्ति नहीं करनी चाहिए क्योंकि निर्माणकर्ता प्रकार तर्क नहीं देता है (यह सामान्य नहीं है)। जब आप कुछ भी आपूर्ति करते हैं, तो उन्हें नजरअंदाज कर दिया जाता है, यही कारण है कि इससे कोई फर्क नहीं पड़ता कि आप कितने या कितने की आपूर्ति करते हैं।

अर्थहीन प्रकार के तर्कों की अनुमति क्यों है?

लिंक के लिए @ स्लाव के साथ धन्यवाद संपादित करें: जावा सभी विधि कॉलों पर टाइप तर्क देता है। यदि बुलाया विधि सामान्य है, तो टाइप तर्क का उपयोग किया जाता है; यदि नहीं, तो उन्हें नजरअंदाज कर दिया जाता है। उदाहरण के लिए:

    int length = "My string".<List>length();

हाँ, यह बेतुका है। जावा लैंग्वेज स्पेसिफिकेशन (JLS) यह उपधारा 15.12.2.1 में औचित्य प्रदान करता है:

यह नियम संगतता की संगतता और सिद्धांतों के मुद्दों से उपजा है। चूंकि इंटरफेस या सुपरक्लास को उनके उपप्रकारों के स्वतंत्र रूप से उत्पन्न किया जा सकता है, इसलिए हम एक गैर-सामान्य के साथ एक सामान्य विधि को ओवरराइड कर सकते हैं। हालाँकि, ओवरराइडिंग (गैर-जेनेरिक) विधि जेनेरिक विधि के लिए कॉल पर लागू होनी चाहिए, जिसमें कॉल्स भी शामिल हैं जो स्पष्ट रूप से तर्क पास करते हैं। अन्यथा उपप्रकार इसके जेनरेट किए गए सुपरटेप के लिए प्रतिस्थापित नहीं होगा।

तर्क उन कंस्ट्रक्टर्स के लिए नहीं है क्योंकि उन्हें सीधे ओवरराइड नहीं किया जा सकता है। लेकिन मुझे लगता है कि वे पहले से ही जटिल नियमों को भी जटिल नहीं बनाने के लिए एक ही नियम चाहते थे। किसी भी स्थिति में, तात्कालिकता पर धारा 15.9.3 और एक बार से अधिक 15.12.2 को संदर्भित करता है।

लिंक

मैं हाल ही में इस असामान्य (मेरे लिए) जावा सिंटैक्स में आया हूँ ... यहाँ इसका एक उदाहरण है:

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

<String, Long> प्रकार के तर्क की स्थिति पर ध्यान दें ... यह प्रकार के बाद सामान्य नहीं है लेकिन पहले। मुझे लगता है मैं इस वाक्यविन्यास से पहले कभी नहीं देखा है स्वीकार नहीं करते। यह भी ध्यान दें कि 2 प्रकार के तर्क हैं जब ArrayList केवल 1 है।

क्या टाइप आर्ग्युमेंट्स की पोजिशनिंग का वही मतलब है जो उन्हें टाइप करने के बाद डालते हैं? यदि नहीं, तो अलग स्थिति का क्या मतलब है?

जब ArrayList केवल 1 हो तो 2 प्रकार के तर्क देना कानूनी क्यों है?

मैंने सामान्य स्थानों को खोजा है, जैसे। एंजेलिका लैंगर और यहां पर लेकिन ANTLR प्रोजेक्ट पर जावा व्याकरण फ़ाइल में व्याकरण के नियमों के अलावा कहीं भी इस वाक्यविन्यास का कोई उल्लेख नहीं मिल सकता है।


जाहिरा तौर पर आप किसी भी जेनेरिक पैरामीटर के साथ किसी भी गैर-जेनेरिक विधि / निर्माणकर्ता को पसंद कर सकते हैं:

new <Long>String();
Thread.currentThread().<Long>getName();

संकलक परवाह नहीं करता है, क्योंकि यह वास्तविक जेनेरिक मापदंडों के प्रकार के तर्कों से मेल नहीं खाता है।

जैसे ही संकलक को तर्कों की जांच करनी होती है, यह एक बेमेल के बारे में शिकायत करता है:

Collections.<String, Long>singleton("A"); // does not compile

मुझे एक संकलक बग की तरह लगता है।





generic-type-argument