2015-11-16 6 views
5

की सूची में ऑब्जेक्ट की कास्ट सूची मैं प्रतीत होता है कि समान रूप से समान कोड के विभिन्न संकलन परिणाम को समझने की कोशिश कर रहा हूं। ऐसा लगता है कि List<Object> को List<T> पर डालना संभव है, लेकिन केवल T ठोस वर्ग द्वारा बाध्य नहीं है। तो class Test<T extends BigDecimal> और न ही class Test<T extends BigDecimal & CharSequence> में class Test<T> में और साथ ही class Test<T extends CharSequence> में लेकिन नहीं दिया ...कक्षा 'प्रकार पैरामीटर

List<Object> bis = new ArrayList<>(); 

निम्नलिखित संकलित करता है।

List<T> result = (List<T>) bis; 

तो जहां अंतर T एक वर्ग के प्रकार और एक अंतरफलक प्रकार से घिरा के लिए से आता है?

संपादित:

अनुरोध के अनुसार कुछ पूरा कोड। यह लाइन 9 में एक कंपाइलर चेतावनी के साथ संकलित करता है। यह वास्तव में result की वस्तुओं पर परिचालन के रूप में असुरक्षित है जैसे कि CharSequence के उदाहरण ClassCastException में परिणाम थे। लाइन 9 में

public class Sandbox<T extends BigDecimal> { 

    public static void main(String[] args) { 
     new Sandbox<BigDecimal>().foo(); 
    } 

    private void foo() {  
     List<Object> bis = Arrays.asList(Integer.valueOf(1)); 
     List<T> result = (List<T>) bis; 
     System.out.println(result); 
    } 

} 

संकलक त्रुटि:

public class Sandbox<T extends CharSequence> { 

    public static void main(String[] args) { 
     new Sandbox<CharSequence>().foo(); 
    } 

    private void foo() {  
     List<Object> bis = Arrays.asList(Integer.valueOf(1)); 
     List<T> result = (List<T>) bis; 
     System.out.println(result); 
    } 
} 

हालांकि, इस सब पर संकलित करता है नहीं List<T> को List<Object> नहीं दिया जा सकता।

+1

अधिक कोड की आवश्यकता है। क्या आप सटीक रेखाएं दे सकते हैं जो आपके लिए असफल हो रही हैं? – markspace

+1

'सूची ' सूची '' पर 'टी 0' मूल्य को अलग करने के लिए सुरक्षित नहीं है, जहां 'T' 'ऑब्जेक्ट' से भिन्न मूल्य ले सकता है। इंटरफ़ेस प्रकार * बनाम *। कक्षा का कोई फर्क नहीं पड़ता। चाहे कोई भी जावा कंपाइलर समस्या का निदान करता है, एक अलग सवाल है। –

+1

'टी विस्तारित करता है CharSequence' संस्करण संकलित नहीं करता है। https://ideone.com/ySVuPr –

उत्तर

0

अच्छी तरह से इस List<Object> bis = Arrays.asList(Integer.valueOf(1)); स्पष्ट रूप से संकलित नहीं है क्योंकि Arrays.asList(Integer.valueOf(1))List<Integer> वापस आ जाएगी, यही कारण है कि आप Cannot cast List<Object> to List<T> मिलता है।

दूसरा मामला, ग्रहण T extends CharSequence के साथ बेतुका रूप से संकलित करता है लेकिन मैंने एक ऑनलाइन कंपाइलर के साथ जांच की है और यह संकलित नहीं है, इसलिए संभवतः यह एक ग्रहण बग है।

+0

वास्तव में, 'सूची bis = Arrays.asList (Integer। valueOf (1)); 'संकलित करता है। जावा के पुराने संस्करणों में यह केवल एक स्पष्ट प्रकार तर्क 'सूची बीआईएस = Arrays के साथ संकलित होगा। asList (Integer.valueOf (1)); ', लेकिन अब जावा ने प्रकार अनुमान लगाया है और यह किसी भी तरह से काम करता है। –

+1

@ पॉल यू सही, मैंने jdk7 – Ramanlfc

+0

का उपयोग किया यह पहला जवाब है और ग्रहण कंपाइलर को गलत व्यवहार के रूप में वर्णित करता है, जो कि निष्कर्ष निकाला गया है, जो मूल रूप से विश्वास करता है कि मुझे कुछ भाषा अंतर्ज्ञान नहीं समझते हैं। @ पॉलबोडिंगटन आपकी मूल्यवान टिप्पणियों के लिए भी धन्यवाद। – gdabski

0

ऐसे व्यवहार को समझने की कुंजी यह समझ रही है कि टाइप एरर वास्तव में करता है। लोकप्रिय धारणा के बावजूद कि रनटाइम पर प्रकार पैरामीटर हटा देता है - यह वास्तव में इस तरह से काम नहीं करता है। यह क्या करता है - यह उन्हें पैरामीटर सीमाओं को घोषित करने के लिए कम करता है। तो कहीं भी आप List<T> टाइप करते हैं जहां T सीमाएं हैं, यह वास्तव में List<[lower-bound-of-T]> तक कम हो गई है। एक CharSequence, List<Object>List<T> लिए डाली और Object के बाद से नहीं है नहीं किया जा सकता (क्योंकि इसका मतलब है कम से कम List<CharSequence>)

ऐसा क्यों होता है? कल्पना कीजिए कि आपके Sandbox वर्ग विधि है कि प्रकार टी के पैरामीटर को स्वीकार करता है:

public class Sandbox<T extends CharSequence> { 
    void bar(T param) { 
     //... 
    } 
} 

bar(T)T की और T स्वीकार कर सकते हैं कुछ भी है कि CharSequence फैली है, इसलिए मूल रूप से रनटाइम पर यह प्रभावी रूप से

void bar(CharSequence param) { 
    //... 
} 

और के रूप में काम करता है इस प्रकार यह सरल Object स्वीकार नहीं कर सकता है।यही कारण है कि केवल खाली खाली पैरामीटर बाध्य मौजूदा ...<Object>

से मुक्त जानवरों को प्रतिबंधित करता है इसके अलावा, वाइल्डकार्ड ? टाइप पैरामीटर केवल आपके दिमाग को उड़ा सकता है। यह कंपाइलर कुछ कहता है जैसे "मुझे नहीं पता कि यह क्या है लेकिन मुझे पूरा यकीन है कि यह सभी सीमाओं" को संतुष्ट करता है। बहुत अजीब है कि इस तथ्य सहित, आप इसे पर कास्ट कर सकते (लगभग?) कुछ भी है, इसलिए यह संभव बनाता है

List<Object> bis = Arrays.asList(Integer.valueOf(1)); 
    List<T> result = (List<T>) (List<?>) bis; 

इसलिए, जब जेनरिक के साथ वर्ग डिजाइन करने के लिए आता है, आप बहुत, बहुत सावधान रहना चाहिए।

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