यह आप पर निर्भर करता है क्या जरूरत है क्या करना है। यदि आप कुछ ऐसा करना चाहते हैं, तो आपको बंधे हुए प्रकार के पैरामीटर का उपयोग करना होगा:
public <T extends Shape> void addIfPretty(List<T> shapes, T shape) {
if (shape.isPretty()) {
shapes.add(shape);
}
}
यहां हमारे पास एक List<T> shapes
और एक है T shape
, इसलिए हम सुरक्षित रूप से कर सकते हैं shapes.add(shape)
। यदि यह घोषित किया गया था List<? extends Shape>
, तो आप इसे सुरक्षित रूप से नहीं कर सकते add
(क्योंकि आपके पास List<Square>
ए Circle
) हो सकता है ।
तो एक बंधे हुए प्रकार के पैरामीटर को एक नाम देकर, हमारे पास यह विकल्प है कि हम इसे अपने जेनेरिक विधि में कहीं और उपयोग करें। यह जानकारी हमेशा आवश्यक नहीं है, निश्चित रूप से, इसलिए यदि आपको यह जानने की ज़रूरत नहीं है कि प्रकार (जैसे आपका drawAll
) के बारे में, तो बस वाइल्डकार्ड पर्याप्त है।
यहां तक कि अगर आप फिर से बंधे हुए प्रकार के पैरामीटर का जिक्र नहीं कर रहे हैं, तो एक बंधे प्रकार के पैरामीटर की आवश्यकता तब भी होती है जब आपके पास कई सीमाएं होती हैं। यहाँ एंजेलिका लैंगर के जावा जेनरिक एफएक्यू से एक उद्धरण दिया गया है
एक वाइल्डकार्ड बाउंड और एक प्रकार के पैरामीटर बाउंड के बीच क्या अंतर है?
एक वाइल्डकार्ड में केवल एक बाउंड हो सकता है, जबकि एक प्रकार के पैरामीटर में कई सीमाएं हो सकती हैं। एक वाइल्डकार्ड में एक निचला या एक ऊपरी बाउंड हो सकता है, जबकि एक प्रकार के पैरामीटर के लिए कम बाउंड जैसी कोई चीज नहीं होती है।
वाइल्डकार्ड सीमा और प्रकार पैरामीटर सीमा अक्सर भ्रमित होती हैं, क्योंकि वे दोनों सीमाएं कहलाती हैं और समान सिंटैक्स में होती हैं। [...]
सिंटैक्स :
type parameter bound T extends Class & Interface1 & … & InterfaceN
wildcard bound
upper bound ? extends SuperType
lower bound ? super SubType
एक वाइल्डकार्ड में केवल एक बाउंड हो सकता है, या तो कम या ऊपरी बाउंड। वाइल्डकार्ड सीमा की सूची की अनुमति नहीं है।
एक प्रकार का पैरामीटर, बाधा में, कई सीमाएं हो सकती हैं, लेकिन एक प्रकार के पैरामीटर के लिए निचली सीमा जैसी कोई चीज नहीं है।
प्रभावी जावा 2 संस्करण से कोटेशन, आइटम 28: एपीआई लचीलापन बढ़ाने के लिए बंधे वाइल्डकार्ड का उपयोग करें :
अधिकतम लचीलेपन के लिए, इनपुट मापदंडों पर वाइल्डकार्ड प्रकारों का उपयोग करें जो उत्पादकों या उपभोक्ताओं का प्रतिनिधित्व करते हैं। […] PECS का उद्देश्य उत्पादक- extends
, उपभोक्ता- super
[…]
वाइल्डकार्ड प्रकारों का उपयोग रिटर्न प्रकारों के रूप में न करें । अपने उपयोगकर्ताओं के लिए अतिरिक्त लचीलापन प्रदान करने के बजाय, यह उन्हें क्लाइंट कोड में वाइल्डकार्ड प्रकारों का उपयोग करने के लिए मजबूर करेगा। उचित रूप से उपयोग किए जाने वाले, वाइल्डकार्ड प्रकार एक वर्ग के उपयोगकर्ताओं के लिए लगभग अदृश्य हैं। वे उन तरीकों को स्वीकार करने के तरीकों का कारण बनते हैं जिन्हें उन्हें स्वीकार करना चाहिए और उन्हें अस्वीकार करना चाहिए। यदि वर्ग के उपयोगकर्ता को वाइल्डकार्ड प्रकारों के बारे में सोचना है, तो संभवतः कक्षा के एपीआई के साथ कुछ गड़बड़ है ।
PECS सिद्धांत को लागू करते हुए, हम अब अपने addIfPretty
उदाहरण पर वापस जा सकते हैं और निम्नलिखित लिखकर इसे और अधिक लचीला बना सकते हैं :
public <T extends Shape> void addIfPretty(List<? super T> list, T shape) { … }
अब हम addIfPretty
कह सकते हैं, ए Circle
, टू, ए List<Object>
। यह स्पष्ट रूप से टाइपसेफ़ है, और फिर भी हमारी मूल घोषणा इतनी लचीली नहीं थी कि यह अनुमति दे सके।
संबंधित सवाल
सारांश
- बंधे हुए प्रकार के मापदंडों / वाइल्डकार्ड का उपयोग करें, वे आपके एपीआई के लचीलेपन को बढ़ाते हैं
- यदि प्रकार को कई मापदंडों की आवश्यकता होती है, तो आपके पास बाध्य प्रकार पैरामीटर का उपयोग करने के अलावा कोई विकल्प नहीं है
- यदि इस प्रकार को एक निम्नतर की आवश्यकता है, तो आपके पास बाउंडेड वाइल्डकार्ड का उपयोग करने के अलावा कोई विकल्प नहीं है
- "प्रोड्यूसर्स" में अपरबाउंड्स होते हैं, "उपभोक्ताओं" में लोअरबाउंड्स होते हैं
- रिटर्न प्रकारों में वाइल्डकार्ड का उपयोग न करें