public class Test {
public static class Nested<T> {
public T val;
Nested(T val) { this.val = val; }
}
public static void main(String[] args) {
Nested<Integer> a = new Nested<Integer>(5);
Nested<Integer> b = new Nested<Integer>(2);
Integer diff = a.val - b.val;
}
}
उपरोक्त कोड ठीक काम करता है। हालांकि, अगर मैं नेस्ट के लिए एक विधि जोड़ें:जावा के प्रकार का मिटा क्यों नहीं टूटता है?
T diff(Nested<T> other) { return this.val - other.val; }
मैं एक संकलन त्रुटि मिलती है:
operator - cannot be applied to T,T
यह मेरे लिए समझ में आता है। टी का प्रकार रनटाइम पर मिटा दिया जाता है, इसलिए जावा ऑपरेटर को लागू नहीं कर सकता है जिसे केवल इंटीजर जैसे कुछ वर्गों के लिए परिभाषित किया जाता है। लेकिन a.val - b.val
क्यों काम करता है?
संपादित करें:
बहुत सारे अच्छे उत्तरों। सबको धन्यवाद। इसका अर्थ, अगर मैं सही ढंग से समझता हूं, तो यह है कि संकलक a.val - b.val
में इंटीजर को जोड़ सकता है क्योंकि यह जानता है कि a
और b
Nested
के रूप में तत्काल थे। हालांकि, <Integer
>this.val - other.val
एक सामान्य फ़ंक्शन परिभाषा के शरीर के अंदर होता है (जहां टी अभी भी कुछ भी हो सकता है), कंपाइलर उन कैस्ट को नहीं जोड़ सकता जो "-
" काम करने के लिए आवश्यक होंगे। इससे एक और दिलचस्प सवाल होता है, अर्थात्, यदि जावा कंपाइलर इनलाइनिंग करने में सक्षम था, तो क्या काम करने के लिए अलग-अलग कार्य के लिए यह संभव होगा?
'एवल' का प्रकार संकलन-समय पर पहले मामले में 'इंटेगर' होने के लिए जाना जाता है, लेकिन दूसरे मामले में केवल 'टी' होता है। दूसरे मामले में, विचार करें कि क्या होता है यदि कोई अन्य मॉड्यूल कुछ वर्ग 'Foo' के लिए' test.Nested 'को तत्काल करता है। –
nneonneo
विशेष रूप से, कंपाइलर 'a.val' और 'b.val' अभिव्यक्तियों के सामने एक' (पूर्णांक) 'कास्ट डालता है। यही जेनेरिक है। –