2011-12-26 17 views
9

इस चर्चा पर एक प्रश्न का पालन की तरह है:जावा 7 डायमंड ऑपरेशन विधि कॉल में

Why doesn't the diamond operator work within a addAll() call in Java 7?

जावा ट्यूटोरियल से,

http://docs.oracle.com/javase/tutorial/java/generics/gentypeinference.html

ध्यान दें कि हीरा अक्सर विधि कॉल में काम करता है; हालांकि, अधिक स्पष्टता के लिए, यह सुझाव दिया जाता है कि आप मुख्य रूप से एक चर को प्रारंभ करने के लिए हीरा का उपयोग करते हैं जहां इसे

तो, मैं पहली पंक्ति के बारे में थोड़ा उलझन में हूं। जब विधि कॉल में हीरा कार्य करता है?

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20type%20argument%20inference%20for%20constructors:

एक कैसे हीरा ऑपरेटर काम करता है यहां पाया जा सकता के बारे में अधिक विवरण के सा?

और इस से, मैं निम्नलिखित है, जो ठीक काम करता है की कोशिश की है:

दें मेरे पास है:

private static class Box<T>{ 
    public Box(T t){} 
} 
static void f(Box<Integer> box){} 

निम्नलिखित की तरह एक फोन ठीक संकलित:

f(new Box<>(new Integer(10))); 

उपरोक्त f() की विधि कॉल में कन्स्ट्रक्टर का आविष्कार करने में पैरामीटर टाइप करें कन्स्ट्रक्टर (यानी Integer) के तर्क से अनुमानित है।

तो यह क्या मतलब है जब ट्यूटोरियल कहते

ध्यान दें कि हीरे अक्सर विधि में काम करता है कॉल

यदि नहीं, तो तरह पर्याप्त किसी को भी एक उदाहरण प्रदान करने के लिए कर सकते हैं जहां हीरे काम करता है विधि कॉल में?

+0

@ गुरंग इसका एक टाइपो है। कट और पेस्ट का खराब मामला :( –

उत्तर

3

तो यह है कि क्या मतलब है जब ट्यूटोरियल कहते

मैं हाँ लगता है, हालांकि वहाँ gotchas के एक जोड़े जब यह <> ऑपरेटरों की बात आती है।

आपके मामले में, बॉक्स तत्काल एक गैर-मुद्दा है कि इस प्रकार का निर्माण कन्स्ट्रक्टर तर्क का उपयोग करके त्रिकोणीय रूप से अनुमानित किया जा सकता है। Integer या T में "नहीं" लेने के लिए कन्स्ट्रक्टर को बदलने का प्रयास करें और देखें कि आमंत्रण कैसे विफल रहता है।

class Testi<R> {  
    public void doIt(Set<? extends R> sets) { 
    } 

    public static void main(final String[] args) { 
      // works since type inference is now possible 
     new Testi<CharSequence>().doIt(new HashSet<>(Arrays.asList("a"))); 

      // fails; nothing which can help with type inference 
     new Testi<CharSequence>().doIt(new HashSet<>(); 
    }  
} 

इसी तरह, अपने लिंक किए गए प्रश्न (addAll के बारे में) में समस्या केवल एक सा संकलक की मदद के रूप में निम्नानुसार द्वारा हल किया जा सकता है::

class BadBox<T> { 

    private T t; 

    public BadBox(){}  

    public void setT(T t) { 
     this.t = t; 
    } 

    static void f(BadBox<Integer> box){} 

    public static void main(final String[] args) { 
     f(new BadBox<>()); //fails, should have worked ideally 
    }  
} 

इसी तरह, इस वर्ग पर एक नजर है

List<String> list = new ArrayList<>(); 
list.add("A"); 

// works now! use only if you love diamond operator ;) 
list.addAll(new ArrayList<>(Arrays.asList(new String[0]))); 
// or the old-school way 
list.addAll(new ArrayList<String>())); 

डायमंड ऑपरेटर भी तोड़ने के लिए जब यह इस प्रकार है गुमनाम वर्गों को लागू करने की बात आती है:

final String[] strings = { "a", "b", "c" }; 
Arrays.sort(strings, new Comparator<>() { 
    @Override 
    public int compare(String o1, String o2) { 
     return 0; 
    } 
}); 

सौभाग्य से, इस मामले में, संकलक यह उल्लेख करने में काफी स्पष्ट है कि <> गुमनाम वर्गों के साथ काम नहीं करेगा/नहीं करेगा।

+1

अच्छा उत्तर +1। –

0

यह वास्तव में विधि आमंत्रण के बारे में नहीं है। स्टैंडअलोन स्टेटमेंट

new Box<>(new Integer(10)); 

भी संकलित करता है। (पूर्णांक तर्क से अर्थात्) Box के लिए T अनुमान लगाने के लिए

दूसरी ओर पर्याप्त जानकारी कर रहे हैं, इस

new ArrayList<>(); 

वहाँ कोई रास्ता नहीं पता है कि सूची की तरह वांछित है संकलन नहीं है।

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

इस काम करता है क्योंकि अनुमान लक्ष्य प्रकार Collection<String>

+1

'नया ऐरेलिस्ट <>(); 'स्टैंड-अलोन कथन * * संकलित करता है। – Holger

1

मुझे नहीं लगता है कि यह जब यह काम करता है और जब नहीं के बारे में सोच के लायक है है से मदद की है। कंपाइलर आपको बताएगा और इस प्रकार आपको फिर से लिखना होगा कि क्या काम नहीं कर रहा है।

इसके पीछे कोई असली तर्क नहीं है; ऐसा लगता है कि डेवलपर्स ने वास्तविक संकलक के कार्यान्वयन की वर्तमान सीमाओं को विशिष्ट समय पर विनिर्देशन में रखा है और हमें बताया है: इस तरह यह होना चाहिए।

जावा 8 नरक ठंडे बिना इन सीमाओं में से कई को हटा देता है। जैसे

Arrays.asList("foo", "bar").addAll(new ArrayList<>()); 

बिना किसी त्रुटि के जावा 8 के साथ संकलित करता है। और क्यों नहीं?

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