2011-08-09 7 views
11

जावा में पैरामीटर प्रकार के साथ, नियम कैसे जांचते हैं कि पैरामीटर अपने बाध्य काम के भीतर ठीक वाइल्डकार्ड के लिए है?जावा जेनेरिक प्रकार में वाइल्डकार्ड पैरामीटर के लिए इसकी सीमाओं के भीतर औपचारिक स्थितियां क्या हैं?

इस तरह एक वर्ग को देखते हुए:

class Foo<T extends Number> {} 

क्या संकलक स्वीकार करता है सीखता है कि के साथ प्रयोग:

  • एक असंबंधित इंटरफ़ेस प्रकार का उपयोग कर एक ? extends वाइल्डकार्ड अनुमति दी है: Foo<? extends Runnable> मान्य है
  • एक ? extends एक असंबंधित वर्ग प्रकार का उपयोग कर वाइल्डकार्ड की अनुमति नहीं है: Foo<? extends Thread> अमान्य है। यही कारण है कि समझ में आता है, क्योंकि कोई प्रकार दोनों Number और Thread
  • की एक उप-प्रकार एक ? super वाइल्डकार्ड में हो सकता है, वाइल्डकार्ड में लोअर बाउंड प्रकार चर के लिए बाध्य की उप-प्रकार होना चाहिए: Foo<? super Runnable> अनुमति नहीं है क्योंकि Runnable एक उप प्रकार नहीं है Number का। फिर, यह प्रतिबंध सही समझ में आता है।

लेकिन ये नियम कहां परिभाषित किए गए हैं? Java Language Specification section 4.5 को देखते हुए, मुझे कक्षाओं से इंटरफेस को अलग करने में कुछ भी दिखाई नहीं देता है; और जब JLS Foo<? super Runnable> की मेरी व्याख्या लागू करने के लिए वैध कहा जाता है। तो मैंने शायद कुछ गलत समझा।

JLS के उस अनुभाग से:: यहाँ मेरी प्रयास है

एक पैरामिट्रीकृत प्रकार कक्षा या इंटरफ़ेस नाम सी के होते हैं और एक वास्तविक प्रकार तर्क सूची < टी 1, ..., Tn>। यह एक संकलित समय त्रुटि है यदि सी सामान्य वर्ग या इंटरफ़ेस का नाम नहीं है, या यदि वास्तविक प्रकार तर्क सूची में प्रकार तर्कों की संख्या सी के घोषित प्रकार पैरामीटर की संख्या से अलग है, तो निम्न में, जब भी हम बोलते हैं एक वर्ग या इंटरफ़ेस प्रकार के, हम सामान्य संस्करण भी शामिल करते हैं, जब तक कि स्पष्ट रूप से बहिष्कृत न किया जाए। इस खंड के दौरान, ए 1, ..., ए के औपचारिक प्रकार पैरामीटर हो, और बी को बी के घोषित बाध्य होने दें। नोटेशन [एआई: = टीआई] प्रकार टीआई के साथ प्रकार परिवर्तनीय एआई के प्रतिस्थापन को इंगित करता है, 1 < = i < = n के लिए, और इस विनिर्देश के दौरान उपयोग किया जाता है।

पी = जी < टी 1, ..., टीएन> पैरामीटरयुक्त प्रकार बनें। यह मामला होना चाहिए कि, पी को कैप्चर रूपांतरण (§5.1.10) के अधीन किया गया जिसके परिणामस्वरूप जी < एक्स 1, ..., एक्सएन>, प्रत्येक वास्तविक प्रकार के तर्क Xi, 1 < = i < = n, क्सी <: बीआई [ए 1: = एक्स 1, ..., एन: = एक्सएन] (§4.10), या एक संकलन समय त्रुटि होती है। कि देता है सी = Foo, n = 1, टी 1 = ? super Runnable और बी 1 = Number:

पी = Foo<? super Runnable> है कि लागू करें।

कब्जा रूपांतरण के लिए definition of capture conversion के इस हिस्से लागू होता है:

तो ती प्रपत्र की एक वाइल्डकार्ड प्रकार तर्क है? सुपर बाय, फिर सी एक ताजा प्रकार का चर है जिसका ऊपरी बाउंड उई [ए 1: = एस 1, ..., एन: = एसएन] है और जिसका निचला बाउंड बीआई है।

जी < X1 देता है यही कारण है कि, ..., xn> = Foo<X> जहां X ऊपरी बाध्य Number के साथ एक नई प्रकार चर रहा है और Runnable बाध्य कम है। मुझे इस प्रकार के एक प्रकार परिवर्तनीय को स्पष्ट रूप से मना करने वाला कुछ भी दिखाई नहीं देता है।

बी 1 = Number में कोई प्रकार के चर नहीं हैं, इसलिए बीआई [ए 1: = एक्स 1, ..., एन: = एक्सएन] अभी भी Number है। XNumber है के रूप में ऊपरी सीमा (कब्जा रूपांतरण से आ रही है), और the subtyping rules के अनुसार, "एक प्रकार चर के प्रत्यक्ष supertypes प्रकार अपनी बाध्य में सूचीबद्ध हैं", इसलिए X <: Number (= द्वि [A1: = एक्स 1, ..., एक: = एक्सएन]), तो यह पैरामीटर इसकी सीमाओं के भीतर है। (लेकिन यह नहीं है!)

उसी तर्क के बाद प्रत्येक वाइल्डकार्ड अपनी सीमाओं के भीतर है, इसलिए यहां कुछ सही नहीं है ... लेकिन यह तर्क वास्तव में गलत कहां गया? कैसे इन नियमों काम जब सही ढंग से लागू करते हैं? जेनरिक पर

उत्तर

5

JLS अधूरा है, और आप इसे में एक और छेद पकड़ लिया। लोअर प्रकार चर पर बाध्य मुश्किल से चर्चा की है, और मैं कल्पना में किसी भी प्रतिबंध नहीं दिख रहा है या तो पर X ऊपरी Number बाध्य होने और Runnable बाध्य कम है। उन्होंने शायद इसे छोड़ दिया।

Intuitively, कम से कम एक संभव प्रकार है कि संतुष्ट ऊपरी बाध्य है और एक प्रकार चर के लिए बाध्य निचले दोनों, अन्यथा चर और सभी प्रकार चर का उपयोग कर बेकार हो सकता है किया जाना चाहिए। चूंकि यह लगभग निश्चित रूप से एक प्रोग्रामिंग गलती है, संकलन विफल होना चाहिए।

यह ऊपरी बाध्य और लोअर बाउंड प्रकार के एक खाली सेट कर जांच करने के लिए आसान है। निचले बाउंड के सभी सुपर प्रकार ज्ञात हैं; उनमें से कम से कम एक, ऊपरी बाध्य किया जाना चाहिए अन्यथा कोई प्रकार दोनों सीमा के भीतर है कि है।

-

दो Foo<? extends A> मामलों में अच्छी तरह से कल्पना में परिभाषित कर रहे हैं। कब्जा रूपांतरण के साथ, हम ऊपरी बाध्य A & Number के साथ नए प्रकार चर X है, और कल्पना के लिए कहते हैं एक ऊपरी बाध्य V1&...&Vm

यह एक संकलन समय त्रुटि है अगर किसी भी दो वर्गों (नहीं इंटरफेस) Vi और वीजे, वी वीजे का उप-वर्ग नहीं है या इसके विपरीत है।

इसलिए यदि ए = थ्रेड, कैप्चर रूपांतरण विफल हो जाता है।