2010-12-13 8 views
13

मैंने 5.1.10 Capture Conversion की जेएलएस वार्ता देखी है, लेकिन मैं यह समझने में असफल हूं कि वे क्या हैं।जावा में कैप्चर रूपांतरण क्या है और क्या कोई मुझे उदाहरण दे सकता है?

क्या कोई उन्हें मुझे समझा सकता है/उदाहरण दे सकता है?

+0

कोई उदाहरण नहीं अन्य तुरंत नीचे चर्चा की तुलना में जाँच कर रहे हैं? –

+0

यह सच है, वे एक उदाहरण प्रदान करते हैं, लेकिन इससे, मैं समझ नहीं पाया कि रूपांतरण कैप्चर क्या हैं। क्या आप उदाहरण समझ गए थे? यदि हां, तो क्या आप कृपया मुझे बता सकते हैं कि वे क्या हैं। धन्यवाद। –

उत्तर

18

कैप्चर रूपांतरण को वाइल्डकार्ड (जेनेरिक में) बनाने के लिए डिज़ाइन किया गया था, ? उपयोगी।

मान लीजिए हम निम्न वर्ग है

public interface Test<T> { 
    public void shout(T whatever); 
    public T repeatPreviousShout(); 

} 

और हमारे कोड हमारे पास है, पर कहीं

public static void instantTest(Test<?> test) { 
    System.out.println(test.repeatPreviousShout()); 
} 

क्योंकि test एक कच्चे Test नहीं है और में repeatPreviousShout() के बाद से "मसा" रिटर्न एक ? , संकलक जानता है कि T है जो Test के लिए एक प्रकार पैरामीटर के रूप में कार्य करता है। यह T कुछ अज्ञात T के लिए है, इसलिए संकलक अज्ञात प्रकार को मिटा देता है (वाइल्डकार्ड के लिए, यह Object के साथ बदलता है)। इसलिए repeatPreviousShout()Object देता है।

लेकिन अगर हम किया था,

public static void instantTest2(Test<?> test) { 
    test.shout(test.repeatPreviousShout()); 
} 

संकलक हमें Test<capture#xxx of ?> cannot be applied की तरह कुछ की एक त्रुटि देना होगा (जहां xxx एक नंबर, 337 है जैसे)।

इसका कारण यह है संकलक shout() पर प्रकार सुरक्षा जांच करने की कोशिश करता है, लेकिन क्योंकि यह एक वाइल्डकार्ड प्राप्त किया, यह पता नहीं है क्या T का प्रतिनिधित्व करता है, इसलिए यह एक प्लेसहोल्डर की कब्जा बुलाया बनाता है।

here (Java theory and practice: Going wild with generics, Part 1) से, यह स्पष्ट रूप से कहा गया है:

कब्जा रूपांतरण क्या संकलक, ताकि प्रकार निष्कर्ष के लिए यह अनुमान लगा सकते हैं पर कब्जा कर लिया वाइल्डकार्ड के लिए एक प्लेसहोल्डर प्रकार का नाम निर्माण उस प्रकार होने की अनुमति देता है ।

उम्मीद है कि यह आपकी मदद करता है।

+0

एक अतिरिक्त उदाहरण: http://stackoverflow.com/questions/4449611/can-anyone-give-me-an-example-where-the-eclipse-jdt-creates-an-ast-with-a-captur –

+0

@ जॉन, अगर आप आलेख पढ़ते हैं (आईबीएम वर्क्स से ऊपर दिए गए लिंक), तो आप देखेंगे कि आपके द्वारा दिया गया उदाहरण वहां से आता है। –

1

वाइल्डकार्ड प्रकार तर्कों वाला एक पैरामीटरयुक्त प्रकार वास्तव में एक संघ प्रकार है। उदाहरण

List<? extends Number> = Union{ List<S> | S <: Number } 

2 मामलों में के लिए, बजाय List<? extends Number> का उपयोग कर के, जावा पर कब्जा कर लिया संस्करण List<S>, जहां एस ऊपरी बाध्य Number के साथ एक बस-निर्मित प्रकार चर रहा है उपयोग करता है।

(1) http://java.sun.com/docs/books/jls/third_edition/html/expressions.html

एक अभिव्यक्ति के प्रकार के संकीर्ण करने के लिए। यदि अभिव्यक्ति का प्रकार List<? extends Number> है, तो हम निश्चित रूप से जानते हैं कि ऑब्जेक्ट का रनटाइम प्रकार वास्तव में कुछ ठोस प्रकार एस (S <: Number>) के लिए List<S> है। इसलिए कंपाइलर अधिक सटीक प्रकार के विश्लेषण करने के लिए List<S> का उपयोग करता है।

कैप्चर रूपांतरण व्यक्तिगत रूप से प्रत्येक अभिव्यक्ति पर लागू होता है; यह कुछ गूंगा परिणाम की ओर जाता है:

<T> void test1(List<T> a){} 
<T> void test2(List<T> a, List<T> b){} 

List<?> x = ...; 
test1(x); // ok 
test2(x, x); // error 

(2) http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.10.2

उप-प्रकार में जाँच A :< B जहां A वाइल्डकार्ड तर्क शामिल है। उदाहरण के लिए,

List<? extends Number> :< B 
<=> 
Union{ List<S> | S <: Number} :< B 
<=> 
List<S> :< B, for all S <: Number 

तो प्रभाव में, हम प्रकार के कब्जा कर लिया संस्करण A

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