जावा जेनिक्स को समझने की कोशिश कर रहे एक और नौसिखिया। मैंने पाया कि सभी विषय मैंने पाया है, लेकिन मेरे पास अभी भी बहुत सारे प्रश्न हैं। तुम मुझे निम्नलिखित बातें समझाने कृपया सकते हैं:<? कक्षा> और <विस्तारित करता है? सुपर क्लास> जावा में - यह इस तरह से क्यों काम करता है?
<? extends SomeClass>
का मतलब है कि?
कि इस किसी भी प्रकार के केवलSomeClass
का एक उपवर्ग हो सकता है, "किसी भी प्रकार के", औरextends SomeClass
साधन है। ठीक है, मैं दो प्राथमिक कक्षाओं लिखें:
abstract class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
class Student extends Person {
public Student(String name) {
super(name);
}
}
कक्षा Student
हमारे उदाहरण में ?
हो जाएगा। ? extends Person
, सटीक होने के लिए। तब मैं ArrayList करने के लिए नए छात्र जोड़ने की कोशिश कर रहा हूँ, कि, जैसा कि मैंने ऊपर लिखा से समझते हैं, सभी वर्गों, कि व्यक्ति का उपवर्गों हैं लागू होता है:
Student clarissa = new Student("Clarissa Starling");
List<? extends Person> list = new ArrayList<>();
list.add(clarissa); //Does not compile
ग्रहण कहते हैं:
" विधि ऐड प्रकार सूची तर्क के लिए लागू नहीं है (विद्यार्थी) "
में (# 3-का कब्जा? व्यक्ति फैली) कैसे वर्ग Student
लागू नहीं किया जा सकता जब हम सूची की घोषणा की, <? extends Person>
द्वारा paramethrized, और Student
बिल्कुल वर्ग Person
फैली?
फिर भी, निम्नलिखित कोड:
List<? super Person> list = new ArrayList<>();
list.add(clarissa);
compiles और अच्छी तरह से काम करता है (list.get(0)
, विधि println को पारित कर दिया, मुझे toString
मंगलाचरण के सही परिणाम से पता चलता)। के रूप में मैं समझता हूँ, List<? super Person>
का मतलब है कि मैं इस सूची में किसी भी प्रकार के पारित कर सकते हैं, कि हमारे Person
वर्ग के लिए सुपर प्रकार है (हमारे मामले में यह केवल Object
वर्ग है)। लेकिन हम देखते हैं कि, तर्क के विपरीत, हम अपने List<? super Person>
पर सबक्लास छात्र को आसानी से जोड़ सकते हैं!
ठीक है, एक तरफ हमारी भावनाओं रखा, और देखते हैं, क्या हमारे संग्रह में Clarissa स्टार्लिंग के साथ हो सकता है। चलो हमारे वर्ग Student
लेते हैं, और यह करने के लिए तरीकों की एक जोड़ी जोड़ें:
class Student extends Person {
private int grant;
public Student(String name) {
super(name);
}
public void setGrant(int grant) {
this.grant = grant;
}
public int getGrant() {
return this.grant;
}
}
फिर हम एक वस्तु, इस नए सिरे से कक्षा से instantiated (हमारे वस्तु "Clarissa", उदाहरण के लिए) List<? extends Person>
के पास,। ऐसा करने का मतलब है, हम अपने सुपरक्लास के संग्रह में सबक्लास स्टोर कर सकते हैं। हो सकता है, मैं कुछ fundamenthal विचारों समझ में नहीं आता, लेकिन इस स्तर पर मैं अपने सुपर-क्लास का संग्रह और संदर्भ के बताए चर करने के लिए "Clarissa" विरोध करने के लिए उपवर्ग जोड़ने के बीच कोई अंतर नहीं दिख रहा है, व्यक्ति द्वारा लिखा गया। जब हम अपने सुपरक्लास वैरिएबल का उपयोग करते हैं, तो हम उनमें से किसी एक का इलाज करना चाहते हैं, तो हमारे पास अनावश्यक विधियों की वही कमी है। तो, क्यों List<? extends SomeClass>
उसी तरह काम नहीं करता है, जिसमें List<? super SomeClass>
इसके विपरीत काम करता है?
- मैं
<T>
(या<E>
, या JLS के उचित हिस्से से किसी अन्य पत्र) और<?>
के बीच fundamenthal अंतर समझ में नहीं आता।<T>
और<?>
टाइपधारक हैं, तो हमारे पास दो "कीवर्ड" क्यों हैं (यह प्रतीक कीवर्ड नहीं हैं, मैंने जावा शब्द में दोनों प्रतीकों के भारी अर्थ पर जोर देने के लिए इस शब्द का उपयोग किया है) उसी उद्देश्य के लिए? प्लेसहोल्डरT
एक निश्चित प्रकार के लिए और स्थानों पर जहां हम वास्तविक प्रकार हम इस पर काम करने में सक्षम होने की जरूरत है पता करने की जरूरत में खड़ा -
मान लीजिए कि आपके पास दो वर्ग 'छात्र' और 'शिक्षक' हैं जो 'व्यक्ति' को बढ़ाते हैं। अब, आपने एक सूची 'सूची <बनाई है? व्यक्ति को बढ़ाता है> और मान लीजिए कि आपने इसमें 'छात्र' जोड़ा है, तो आप कैसे सुनिश्चित होंगे कि 'list.get (0)' आपको केवल 'छात्र' वापस कर देगा, न कि 'शिक्षक'? इस अस्पष्टता को रोकने के लिए इसकी अनुमति नहीं है। – user2004685
पढ़ें http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs –
मुझे उम्मीद है कि, list.get (0) एक ऑब्जेक्ट वापस कर देगा, जिसे सुपरक्लास प्रकार में डाला जाएगा, और मैं ' superclass (व्यक्ति) में घोषित, केवल विधियों का आह्वान करने में सक्षम हो जाएगा। –