ये दो उदाहरण समतुल्य हैं, और वास्तव में एक ही बाईटेकोड के लिए संकलित होंगे।
दो तरीके हैं जो एक बंधे हुए जेनेरिक प्रकार को एक विधि में जोड़ते हैं जैसा कि आपका पहला उदाहरण कुछ भी करेगा।
टाइप पैरामीटर को दूसरे प्रकार से पास करना
ये दो विधि हस्ताक्षर बाइट कोड में समान हैं, लेकिन संकलक प्रकार की सुरक्षा को लागू करता है:
public static <T extends Animal> void addAnimals(Collection<T> animals)
public static void addAnimals(Collection<Animal> animals)
पहले मामले में, केवल Collection
(या उपप्रकार) की Animal
अनुमति है। दूसरे मामले में, Collection
जेनेरिक प्रकार या उपप्रकार के साथ (या उपप्रकार) Animal
की अनुमति है।
उदाहरण के लिए, पहली विधि में निम्नलिखित की अनुमति है लेकिन दूसरी नहीं:
List<Cat> cats = new ArrayList<Cat>();
cats.add(new Cat());
addAnimals(cats);
कारण यह है कि दूसरा केवल जानवरों के संग्रह की अनुमति देता है, जबकि पहला किसी भी वस्तु के संग्रह की अनुमति देता है जो जानवर (यानी उपप्रकार) के लिए उत्तरदायी है। ध्यान दें कि यदि यह सूची उन जानवरों की एक सूची थी जो एक बिल्ली को शामिल करने के लिए हुई थीं, तो या तो विधि इसे स्वीकार करेगी: मुद्दा संग्रह का सामान्य विनिर्देश है, न कि इसमें वास्तव में क्या है।
लौटती हुई वस्तु
दूसरी बार जब यह लौटने वाली वस्तुओं के साथ होता है। चलिए मान लेते हैं कि निम्नलिखित विधि मौजूद है:
public static <T extends Animal> T feed(T animal) {
animal.eat();
return animal;
}
आप इसके साथ निम्नलिखित करने में सक्षम होंगे:
Cat c1 = new Cat();
Cat c2 = feed(c1);
हालांकि यह एक विरोधाभासी उदाहरण है, ऐसे मामले हैं जहां यह समझ में आता है। जेनरिक के बिना, विधि को वापस लौटना Animal
होगा और आपको इसे काम करने के लिए टाइप कास्टिंग को जोड़ना होगा (जो कि संकलक वैसे भी बाइट कोड को पर्दे के पीछे जोड़ता है)।
addAnimals(List<Animal>)
बिल्लियों की सूची लिखने और जोड़ने का प्रयास करें !