2013-02-22 40 views
10

मैं अभी भी जेनेरिक के बारे में सीख रहा हूं और एक प्रश्न है।एक सामान्य वर्ग में इन बयानों के बीच क्या अंतर है?

public class Test<T> { 

    public static void main (String[] args) { 
     Test t1 = new Test(); 
     Test<String> t2 = new Test<String>(); 
     Test t3 = new Test<String>(); 
    } 
} 

सभी बयान संकलन लेकिन मैं वास्तव में नहीं पता है कि उन्हें अलग बनाता है: यदि आप इस सामान्य वर्ग था कहो। क्या कोई मुझे उन तीन बयानों पर एक संक्षिप्त स्पष्टीकरण दे सकता है।

+0

लगभग सच। अन्य दो केवल विज्ञापन चेतावनियां, लेकिन वास्तविक संकलन त्रुटि नहीं। –

उत्तर

9
Test t1 = new Test(); 

यहाँ आप एक कच्चे प्रकार उपयोग कर रहे हैं। यानी, generic clas एस के लिए Type argument पास नहीं कर रहा है।

संकलक आप एक चेतावनी यहाँ

टेस्ट देना चाहिए एक कच्चे प्रकार है। सामान्य प्रकार टेस्ट के सन्दर्भ पैरामिट्रीकृत

Test<String> t2 = new Test<String>(); 
यहाँ

होना चाहिए आप जेनरिक का उपयोग कर रहे हैं। type argument के रूप में स्ट्रिंग को generic class पर पास करना।

Test t3 = new Test<String>(); 

संकलक भी यहाँ भी एक चेतावनी आप देना चाहिए:

  • टेस्ट एक कच्चे प्रकार है। सामान्य प्रकार टेस्ट के सन्दर्भ

अपने पहले मामले के रूप में ही parameterized किया जाना चाहिए, लेकिन आप पैरामिट्रीकृत प्रकार का उपयोग कर रहे हैं, जबकि निर्माता लागू।

एक और वर्ग भी है जो + जावा 7 संस्करणों में ठीक काम करता है।

Test<String> t4 = new Test<>(); 

कोई संकलक चेतावनी यहाँ अगर आप + जावा 7 प्रकार निष्कर्ष

इस मामले में की वजह से type inference सामान्य प्रकार के परिचय के कारण का उपयोग मान लिया जाता है, इस प्रकार आप सामान्य प्रदान करने के लिए की जरूरत नहीं है कन्स्ट्रक्टर इनोकेशन के दौरान टाइप करें।

+1

हमें यह भी जोड़ना चाहिए कि मूल प्रश्न दो संयोजनों से चूक गया: 'टेस्ट t4 = नया टेस्ट() ', जो संकलित नहीं होगा क्योंकि यह किसी सामान्य प्रकार के कच्चे प्रकार के संदर्भ को असाइन करने का प्रयास करता है; और 'टेस्ट t5 = नया टेस्ट <>() ', जो जावा 7 में नए" हीरा ऑपरेटर "का उपयोग करके संकलित करता है। – yshavit

+1

+1 और जावा 7 के बाद से आप टेस्ट t4 = नया टेस्ट <>() भी लिख सकते हैं; जो टी 2 घोषणा के बराबर है ... – pgras

+1

@shavit और pgras बस इसे जोड़ दिया :) – PermGenError

2

वे सभी वास्तव में समान ऑब्जेक्ट्स बनाते हैं। एकमात्र अंतर यह होगा कि कोड के बाकी हिस्सों में उन्हें वाक्य रचनात्मक रूप से कैसे माना जाता है।

t1 और t3 ठीक उसी तरह से व्यवहार किया जाएगा क्योंकि वे एक ही प्रकार के हैं - उन्हें कक्षा Test कक्षा के साथ एक वस्तु के रूप में माना जाएगा, और कुछ भी नहीं।

t2 टाइपिंग जांच के मामले में अधिक कठोर व्यवहार किया जाएगा। यदि कुछ मौका संकलक के लिए अपने जेनेरिक <String> गुणवत्ता का उपयोग करने के लिए प्रस्तुत करता है तो उस गुणवत्ता को भी मिलान करने की आवश्यकता होगी।

3

जेनिक्स आपको संकलित-समय प्रकार की जांच देता है।

यह आप/अपने आइटम के साथ क्या नहीं कर सकते हैं के उदाहरण को जोड़ने के लिए मदद करता है (मैं उदाहरण में आसानी के लिए ArrayList को Test बदल दिया है):

ArrayList t1 = new ArrayList(); 
    ArrayList<String> t2 = new ArrayList(); 
    ArrayList t3 = new ArrayList<String>(); 

    // First list can have ANYTHING added to it 
    // Compiler won't check because no generics 
    t1.add(new Integer("7")); 
    t1.add("Hello"); 

    // Second list can only have Strings added to it 
    // Compiler will check and throw compile error for anything else 
    t2.add(new Integer("7")); // doesn't compile 
    t2.add("Hello"); 

    // Third list is interesting... 
    // Again, can have ANYTHING added to it 
    // This is because generics (in Java...) are swapped out at COMPILE time 
    // rather than RUNTIME. The compiler can see that the actual type is just 
    // plain ArrayList 
    // If you like, it's similar to doing: 
    // Object o = (String) new Object(); 
    // The net-effect is everything reduced back to Object 
    t3.add(new Integer("7")); // fine 
    t3.add("Hello");