जेनेरिक विनिर्देश
इससे पहले कि मैं इन्स्टेन्शियशन समस्याओं पर जाने मैं अपने सामान्य संशोधन के लिए, a1
रूप में एक ही त्रुटि देता है परिभाषा:
Outer1<E extends Outer1<E>.Inner1>
बाहरी 1 मूल रूप से इनर 1 या उसके किसी भी बच्चे वर्ग के तत्वों को रखना चाहिए। इसलिए Outer1 वस्तु के प्रकार प्रासंगिकता का नहीं है और निम्न कोड के साथ बदला जा सकता है:
Outer1<E extends Outer1<?>.Innter1>
भी विस्तार वर्गों थोड़ा ऊपर उल्लेख किया है का उपयोग करते हुए संशोधित किया गया है।
आरंभ होने
वस्तुओं की इन्स्टेन्शियशन के लिए आप निम्नलिखित ने कहा:
Outer1<Outer1.Inner1> a1; // WARNING: Outer1.Inner1 is a raw type
a1 = new Outer1<Outer1.Inner1>(); // WARNING: Outer1.Inner1 is a raw type
newacct पहले ही उल्लेख किया गया है, Outer1
ही आप नहीं किया था एक सामान्य प्रकार के साथ घोषित किया जाता है ऑब्जेक्ट को तुरंत चालू करते समय निर्दिष्ट करें। कोड इसलिए बाद एक को बदला जाना चाहिए:
Outer1<Outer1<?>.Innter1> a1; // or simply Outer1<?> a1;
a1 = new Outer1<Outer1<?>.Innter1>(); // or simply a1 = new Outer1<>();
वर्ग है जो कि आधार वर्ग का एक प्रकार के लिए एक आधार वर्ग बढ़ाया असाइन करने के लिए इसी तरह के।
आप जेनेरिक टाइप परिभाषा के साथ निर्दिष्ट करते हैं कि उदाहरण किस प्रकार के तत्व रखेगा।
Outer1<Outer1<?>.Innter1> test;
की तरह एक घोषणा है कि यह भी सामान्य प्रकार से मेल Outer1
का विस्तार किसी भी इंस्टेंस को स्वीकार करेंगे।इसका मतलब है आप केवल असाइन कर सकते हैं
test = new Outer1<Outer1<?>.Inner1>();
test = new Outer2<Outer2<?>.Inner1>();
इसे करने के लिए
, लेकिन नहीं Outer3
या यहाँ तक कि Outer4
!
भले ही आप कोड को आगे बढ़ाने के लिए कोड को संशोधित करते हैं।
public static class Outer5<E extends Outer1<?>.Inner1> extends Outer1<E>{
public class Inner5 extends Inner1 {
}
}
तुम सिर्फ
test = new Outer5<Outer5<?>.Inner1>();
नहीं बल्कि
test = new Outer5<Outer5<?>.Inner5>(); // FAILS!
कुछ है कि प्रकार तर्क के रूप में परिभाषित किया गया Inner1
में जोड़ने के लिए सक्षम हैं।
हालांकि, वास्तव में इस मुद्दे का एक बहुत ही सरल समाधान है। आप इस तरह से वस्तु को परिभाषित हैं:
Outer1<? extends Outer1<?>.Inner1> test2;
आप वास्तव में निम्नलिखित बातें कर पा रहे हैं:
test2 = new Outer1<Outer1<?>.Inner1>();
test2 = new Outer2<Outer2<?>.Inner1>();
test2 = new Outer3<Outer3<?>.Inner3>();
test2 = new Outer4();
test2 = new Outer5<Outer1<?>.Inner1>();
test2 = new Outer5<Outer5<?>.Inner1>();
test2 = new Outer5<Outer5<?>.Inner5>();
के रूप में आप अब स्पष्ट रूप से संकलक से कहा कि या तो Inner1
प्रकार या उसके किसी भी एक्सटेंशन की अनुमति है।
कोड
मैं अपने कोड अद्यतन और सत्यापित करने के लिए है कि वास्तव में किए गए परिवर्तनों को किसी भी कारण स्पष्ट प्रकार तर्क निर्दिष्ट करने के लिए redundant type arguments in new expression
के अलावा त्रुटि या चेतावनी संकलन का उत्पादन नहीं करते नए असाइनमेंट के एक जोड़े को जोड़ दिया है हीरा ऑपरेटर <>
उपयोग करने के बजाय:
public class GenericInnerRecursion
{
// base class, consisting of outer and inner parts
public static class Outer1<E extends Outer1<?>.Inner1> {
public class Inner1 {
}
public void addElement(E e) {
System.out.println("Added " + e.toString());
}
}
// extending outer, but not inner
public static class Outer2<E extends Outer1<?>.Inner1> extends Outer1<E>{
}
// extending both outer and inner
public static class Outer3<E extends Outer3<?>.Inner3> extends Outer1<E>{
public class Inner3 extends Inner1 {
}
}
// extending both outer and inner and stopping extension
public static class Outer4 extends Outer1<Outer4.Inner4> {
public class Inner4 extends Outer1<Inner4>.Inner1 {
}
}
public static class Outer5<E extends Outer1<?>.Inner1> extends Outer1<E>{
public class Inner5 extends Inner1 {
}
}
// instantiating
public static void main(String[] args) {
Outer1<Outer1<?>.Inner1> a1;
a1 = new Outer1<Outer1<?>.Inner1>();
Outer1<?> a2;
a2 = new Outer1<>();
Outer1<Outer1<?>.Inner1> a3;
Outer1<? extends Outer1<?>.Inner1> a4;
a4 = new Outer1<Outer1<?>.Inner1>();
Outer2<Outer1<?>.Inner1> b1;
b1 = new Outer2<Outer1<?>.Inner1>();
// and so on
// assigning extension-classes to the parent-class
Outer1<Outer1<?>.Inner1> c1;
c1 = new Outer2<Outer2<?>.Inner1>();
// assigning inner-extension-classes to parent-class
Outer1<Outer3<?>.Inner3> c2;
c2 = new Outer3<Outer3<?>.Inner3>();
// assigning extension class without specified generics to parent class
Outer1<Outer4.Inner4> c3;
c3 = new Outer4();
Outer1<Outer1<?>.Inner1> test;
test = new Outer1<>();
test = new Outer2<>();
test = new Outer5<Outer5<?>.Inner1>();
Outer1<? extends Outer1<?>.Inner1> test2;
test2 = new Outer1<Outer1<?>.Inner1>();
test2 = new Outer2<Outer2<?>.Inner1>();
test2 = new Outer3<Outer3<?>.Inner3>();
// new Outer3<Outer3<?>.Inner1>(); not possible as generic type extends Outer3<?>.Inner3 and not Outer1<?>.Inner1!
test2 = new Outer4();
test2 = new Outer5<Outer1<?>.Inner1>();
test2 = new Outer5<Outer5<?>.Inner1>();
test2 = new Outer5<Outer5<?>.Inner5>();
}
}
तरह का विस्तार 'Outer4' इस तरह के एक प्रकार का उपयोग करने के लिए (क्योंकि अन्यथा प्रकार parameterizing असीम पुनरावर्ती है) एक ही रास्ता है। क्या आपको कोई सख्त घोषणा की आवश्यकता है? 'ई बाहरीबढ़ाता है। इनर 1' सिरदर्द से बहुत कम होगा। आप इन कक्षाओं का उपयोग कैसे करेंगे? – Radiodef