2013-08-07 6 views
26

अंत में मैं जेनरिक के साथ थोड़ा सा प्रयोग कर रहा हूं। मैं कोड के इस टुकड़े के साथ आया था:जावा: जेनेरिक के साथ प्रयोग

public class Test { 

    static <T> void f(T x) { 
     x = (T) (Integer) 1234; 
     System.out.println(x); 
    } 

    public static void main(String[] args) { 
     f("a"); 
     f(1); 
     f('a'); 
     f(1.5); 
     f(new LinkedList<String>()); 
     f(new HashMap<String, String>()); 
    } 
} 

मैं इस भाग गया और इस उत्पादन मिल गया: बिना किसी अपवाद के

1234 
1234 
1234 
1234 
1234 
1234 

! यह कैसे संभव है?

+0

सावधान रहें - आप खतरनाक रूप से पूछने के करीब भटक रहे हैं: "जेनिक्स क्यों सी ++ टेम्पलेट्स की तरह काम नहीं करते?" –

उत्तर

36

यह type erasure की वजह से है (इस बारे में बहुत कुछ लिखा गया है, बस इस शब्द के लिए Google)। बाइट कोड को f संकलन के बाद विधि इस प्रकार दिखाई देंगे:

static void f(Object x) { 
    x = (Object) (Integer) 1234; 
    System.out.println(x); 
} 

तो System.out.println सिर्फ वस्तु x पर toString विधि कॉल करेगा - और अपने मामले में यह Integer.toString() है।

+1

एक शानदार जवाब है :) –

3

टाइप एरर के कारण। Oracle's documentation से:

जेनेरिक्स जावा भाषा से परिचित कराया संकलन समय पर तंग प्रकार चेकों प्रदान करने के लिए और सामान्य प्रोग्रामिंग का समर्थन करने के। जेनरिक को लागू करने के लिए, जावा के प्रकार विलोपन लागू होता है:

  • यदि प्रकार पैरामीटर असीम हैं उनकी सीमा या वस्तु के साथ सामान्य प्रकार के सभी प्रकार पैरामीटर बदलें। उत्पादित बाइटकोड, इसलिए, केवल सामान्य वर्ग, इंटरफेस और विधियां शामिल हैं।

  • प्रकार सुरक्षा को संरक्षित रखने के लिए आवश्यक प्रकार डालें।

  • विस्तारित जेनेरिक प्रकारों में बहुरूपता को संरक्षित करने के लिए पुल विधियों को उत्पन्न करें।

टाइप एरर सुनिश्चित करता है कि पैरामीटर प्रकारों के लिए कोई भी नई कक्षाएं नहीं बनाई गई हैं; नतीजतन, जेनेरिक कोई रनटाइम ओवरहेड नहीं होता है।

+3

जब आप किसी बाहरी संसाधन के शब्दों की प्रतिलिपि बनाते हैं, तो हमेशा यह सुनिश्चित करें कि आप मूल शब्द को सही ढंग से उद्धृत और लिंक करते हैं। –

संबंधित मुद्दे