2015-08-25 10 views
9

तरहऊपरी बाउंड के साथ मिलान कैप्चर पर टूटी हुई जांच टाइप करें?

public class Play { 
    public static void main(String[] args) throws Exception { 
     outer(Integer.class, inner("abc")); 
    } 

    static <C> void outer(Class<C> c, List<? super C> s){ 
    } 

    static <C> List<C> inner(C c) { 
     return null; 
    } 
} 

एक कक्षा बनाएं और यह जावा 8 में कम्पाइल हो गया! (दोनों ग्रहण 4.5 और JDK1.8_25 में) https://ideone.com/Q9JLHP

ग्रहण में, सीमा सही ढंग से अनुमान लगाया जाता है, लेकिन कैसे कर सकता है outer के कब्जा Supplier<? super Integer> कभी तर्क Supplier<String> से संतुष्ट कर दिया गया ??

संपादित करें: यह स्पष्ट है कि यह जावा 8-विशिष्ट है और उदाहरण को कम भ्रमित कर दिया गया है।

+0

@ bayou.io यह उदाहरण के लिए मैंने केवल मनमाना सामान्य प्रकार चुना है। मुझे यकीन है कि संकलक इसे विशेष रूप से यहां नहीं मानता है। मैं इस भ्रम से बचने के लिए उदाहरण अपडेट करूंगा। –

उत्तर

10

inner("abc") कंपाइलर के विवेकानुसार, String के किसी भी सुपरटेप के Supplier के रूप में व्याख्या किया जा सकता है। - उदाहरण के लिए,

Supplier<Object> inner = inner("abc"); 

काम करता है ठीक है, क्योंकि "abc"भी एक Object है। यही हो रहा है: inner आपको Supplier<Object> लौटा रहा है।

+0

लेकिन यह व्यवहार जावा 8 के लिए नया प्रतीत होता है। इस बदलाव को क्यों बदला गया था इसका कोई संदर्भ? क्योंकि यह हैमक्रिस्ट के 'assertThat()' पर टाइपिंग प्रकार को तोड़ दिया है, जिसका प्रयोग आमतौर पर किया जाता है। –

+1

जावा 8 में [लक्ष्य प्रकार अनुमान] (http://openjdk.java.net/jeps/101) है, जो प्रकार अनुमान जानकारी को एएसटी के साथ-साथ ऊपर फैलाने देता है। यह सामान्य बात के रूप में उनके संदर्भ के लिए सही प्रकार को लैम्बडा को जादुई रूप से समझने के लिए बहुत सख्ती से जरूरी है। –

+2

लैम्ब्डा अभिव्यक्तियों की सहायता के अलावा, यह जेनिक्स के परिचय के बाद मौजूद त्रुटियों को हल करता है, यानी आप 'सूची एल = Arrays.asList (42);' या 'सूची एल = स्थिति' लिख नहीं सकते थे? ...: Collections.emptyList(); ', आदि। यदि यह मौजूदा कोड तोड़ता है, तो यह मौजूदा कोड है जो त्रुटिपूर्ण है क्योंकि उसी कोड को पुराने कंपाइलर को पारित किया होगा जब अनुमानित प्रकार मैन्युअल रूप से डाला जाएगा, यानी यहां 'बाहरी' कहकर (Integer.class, Play। आंतरिक ("एबीसी")); ' – Holger

1

inner पर अनुमान की आवश्यकता है कि CInteger और String का सुपरटेप है।

C बिल्कुल क्या है? यह एक जटिल कहानी है। Integer और String दोनों Object हैं, ज़ाहिर है। लेकिन दोनों Serializable भी हैं! और Comparable<?> भी ....

अंत में, इससे कोई फर्क नहीं पड़ता; हमें यह जानने की जरूरत है कि यह String और Integer का "कम से कम ऊपरी सीमा" है, जिस तरह से यह defined है।

+0

'सी' को 'इंटीजर' और' स्ट्रिंग 'का सुपरटेप नहीं होना चाहिए। 'बाहरी' के हस्ताक्षर में 'सूची' में केवल 'इंटेगर' और 'स्ट्रिंग' के कुछ अनिर्दिष्ट सुपरटेप के तत्व शामिल हैं। –

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