public class Base {
<T> List<? extends Number> f1() {return null;}
List<? extends Number> f2() {return null;}
<T extends Number> List<T> f3() {return null; }
}
class Derived extends Base {
List<String> f1() {return null;} // compiles fine !!!
List<String> f3() {return null; } // compiles fine !!!
// compile ERR: return type is incompatible with Base.f2()
List<String> f2() {return null;}
}
क्यों अधिभावी तरीकों f1() और f3() व्युत्पन्न वर्ग में की परिभाषा व्युत्पन्न वर्ग (जो त्रुटि संकलन "वापसी प्रकार देता में f2() विधि अधिभावी की परिभाषा की तरह, कोई संकलन त्रुटि दिखा सकते हैं बेस के साथ असंगत है। एफ 2() ")?क्यों गैर-जेनेरिक एक सामान्य विधि को ओवरराइड करते समय subsignature और अनचेक नियम रिटर्न प्रकारों पर इस तरह काम करते हैं?
जेएलएस में सब्सिनेचर ओवरराइड नियम गैर-सामान्य होने के लिए ओवरराइडिंग विधि (व्युत्पन्न कक्षा में) की अनुमति देता है, जबकि ओवरराइड विधि (बेस क्लास में) सामान्य है।
अनचेक ओवरराइड नियम बेस क्लास में List<T>
के बजाय उपclass List<String>
में रिटर्न प्रकार बनाने की अनुमति देता है।
लेकिन मैं नीचे व्यवहार में अंतर की व्याख्या नहीं कर सकते हैं, और मुझे समझ नहीं आता क्यों व्युत्पन्न वर्ग में f1() और f3() अधिभावी परिभाषाएँ सफलतापूर्वक संकलन (ग्रहण, SE8 पर), अनदेखी प्रतिबंध के लिए घिरे प्रकार पैरामीटर द्वारा लगाए गए f3() और f1() के लिए बाध्य वाइल्डकार्ड द्वारा!
पीएस मेरा अनुमान - व्युत्पन्न कंपाइलर में f1() और f3() में दोनों विधियों को केवल "कच्ची" सूची लौटने के रूप में व्यवहार किया जाता है - कंपाइलर पहले मिटा देता है (इस पल में केवल व्युत्पन्न में !?) पहले, और फिर इन मिटाए गए तरीकों की तुलना बेरोजगार में बेकार (अब तक) आधार में तरीकों। अब अनचेक ओवरराइडिंग नियम ठीक है (और सीमाओं की जांच करने की कोई आवश्यकता नहीं है - यह केवल असंभव है), संकलक निर्णय लेता है कि यह सही ओवरराइडिंग और संकलन आगे जाता है ... और बेस.एफ 1() और बेस में संकलन जेनरिक के अंत में कहीं .f3() भी मिटा दिया :))
This SO answer इस विषय पर विचार भी जोड़ता है।