2009-06-15 7 views
41

मैंजावा जेनरिक सी ++ टेम्पलेट्स से अलग कैसे हैं? मैं पैरामीटर के रूप में int का उपयोग क्यों नहीं कर सकता?

ArrayList<int> myList = new ArrayList<int>(); 
जावा में

बनाने के लिए कोशिश कर रहा हूँ, लेकिन वह काम नहीं करता।

क्या कोई बता सकता है कि int टाइप पैरामीटर काम क्यों नहीं करता है?
Integerint आदिम कार्यों के लिए कक्षा का उपयोग करते हुए, लेकिन क्या कोई यह समझा सकता है कि int क्यों स्वीकार नहीं किया गया है?

जावा संस्करण 1.6

+0

http://stackoverflow.com/questions/31693/ – n611x007

उत्तर

58

जावा जेनरिक सी ++ टेम्पलेट्स से बहुत अलग हैं कि मैं यहां मतभेदों को सूचीबद्ध करने की कोशिश नहीं कर रहा हूं। (। अधिक जानकारी के लिए What are the differences between “generic” types in C++ and Java? देखें)

इस विशेष मामले में, समस्या यह है कि आप सामान्य प्रकार पैरामीटर के रूप में पुरातन उपयोग नहीं कर सकते है (JLS §4.5.1 देखें: "प्रकार तर्क या तो संदर्भ प्रकार या वाइल्डकार्ड हो सकता है।")।

List<Integer> ints = new ArrayList<Integer>(); 
ints.add(3); // 3 is autoboxed into Integer.valueOf(3) 

ताकि दर्द से कुछ को हटा:

हालांकि, autoboxing के कारण, आप की तरह कर सकते हैं। यह निश्चित रूप से रनटाइम दक्षता को चोट पहुंचाता है, हालांकि।

+3

+1, ठीक है जो मैं कहने जा रहा था! – coobird

+29

जावा जीनिक्स एक ड्रीम विफिन एक ड्रीम है। टाइपएफ़ कोड का ड्वैम पिछड़ा संगतता के ड्यूम को विफिन करता है। –

2

आप जावा में प्रकार पैरामीटर के रूप में पुरातन का उपयोग नहीं कर सकते हैं। जावा एररिक्स टाइप एरर के माध्यम से लायक है, जिसका अर्थ है कि कंपाइलर जांच करता है कि आप उन प्रकारों का उपयोग कर रहे हैं जिन्हें आपने परिभाषित किया है, लेकिन संकलन पर, सबकुछ ऑब्जेक्ट के रूप में माना जाता है। चूंकि int और अन्य प्राइमेटिव ऑब्जेक्ट्स नहीं हैं, इसलिए उनका उपयोग नहीं किया जा सकता है। इसके बजाय, इंटीजर का उपयोग करें।

3

ऐसा इसलिए है क्योंकि int एक आदिम है, यह known issue है।

यदि आप वास्तव में चाहते थे, तो आप अपना स्वयं का संग्रह उपclass/लिख सकते हैं जो ऐसा कर सकता है।

+0

+1 धन्यवाद – yesraaj

+0

@z लिंक कहता है कि 'यह बग उपलब्ध नहीं है' – UnKnown

23

कारण यह नहीं है कि int काम नहीं करता है कि आप जावा में जेनेरिक पैरामीटर के रूप में आदिम प्रकारों का उपयोग नहीं कर सकते हैं।

जैसा कि आप वास्तविक प्रश्न हैं, सी ++ टेम्पलेट जावा जेनरिक से अलग कैसे हैं, जवाब है ... वास्तव में वास्तव में अलग है। यह समान अंत प्रभाव को कार्यान्वित करने के लिए अनिवार्य रूप से दो पूरी तरह से अलग दृष्टिकोण है।

जावा जेनेरिक की परिभाषा पर ध्यान केंद्रित करता है। जेनेरिक परिभाषा की वैधता केवल सामान्य में कोड पर विचार करके जांच की जाती है। यदि पैरामीटर सही ढंग से बाधित नहीं होते हैं तो कुछ क्रियाएं उन पर नहीं की जा सकती हैं। अंततः इसका वास्तविक प्रकार माना जाता है।

सी ++ विपरीत है। टेम्पलेट पर ही न्यूनतम सत्यापन किया जाता है। यह वास्तव में वैध माना जाने के लिए केवल पारदर्शी होना चाहिए। परिभाषा की वास्तविक शुद्धता उस स्थान पर की जाती है जहां टेम्पलेट का उपयोग किया जाता है।

+2

+1 अंतर को समझाने के लिए एक बहादुर प्रयास के लिए :-) (हालांकि मैं सी ++ टेम्पलेट्स के न्यूनतम सत्यापन के साथ समस्या उठा सकता हूं - कोई भी कोड इस पर निर्भर नहीं है टेम्पलेट पैरामीटर पूरी तरह से चेक किया गया है) –

+0

इसके अलावा, लोगों को पता है, सी ++ समुदाय ने आश्रित टेम्पलेट कोड के न्यूनतम सत्यापन के बारे में चिंताओं को संबोधित करने में काफी प्रयास किए हैं (विशेष रूप से जब यह गुप्त त्रुटि संदेशों की ओर जाता है)। सी ++ 0x में टेम्पलेट्स होंगे जिन्हें 'अवधारणाओं' द्वारा बाधित किया जा सकता है और परिभाषा पहली बार सामने आने पर उनकी परिभाषा पूरी तरह से सत्यापित की जाएगी (त्रुटि संदेश अधिक समझदार होंगे)। सी ++ 0 एक्स में पाठ्यक्रम के अनियंत्रित टेम्पलेट्स भी होंगे (जिनके अपने फायदे हैं :)। –

+4

@ फैसल: इसे अद्यतित रखने के लिए, मुझे शायद यह उल्लेख करना चाहिए कि आपकी टिप्पणी "अवधारणाओं" को C++ 0x (अब शायद C++ 0B) से हटा दिया गया है। यह हम एक सार्वभौमिक रूप से लोकप्रिय निर्णय नहीं, हम कहेंगे। –

8

वे बहुत अलग अवधारणाएं हैं, जिनका उपयोग कुछ करने के लिए किया जा सकता है, लेकिन सभी एक ही कार्य नहीं। जैसा कि अन्य प्रतिक्रियाओं में कहा गया है, यह सभी मतभेदों पर जाने के लिए काफी कुछ ले जाएगा, लेकिन यहां मैं व्यापक स्ट्रोक के रूप में देखता हूं।

जेनेरिक जेनेरिक कंटेनर के एक ही त्वरण के माध्यम से रनटाइम पॉलीमोर्फिक कंटेनरों की अनुमति देता है।जावा में, सभी (गैर-आदिम) ऑब्जेक्ट संदर्भ हैं, और सभी संदर्भ समान आकार हैं (और एक ही इंटरफेस में से कुछ हैं), और इसलिए बाइटकोड द्वारा संभाला जा सकता है। हालांकि, बाइट कोड का केवल तात्कालिकता होने का एक आवश्यक निहितार्थ इरेज़र है; आप यह नहीं बता सकते कि कंटेनर किस वर्ग के साथ तत्काल था। यह मौलिक रूप से अलग ऑब्जेक्ट मॉडल की वजह से C++ में काम नहीं करेगा, जहां ऑब्जेक्ट्स हमेशा संदर्भ नहीं होते हैं।

टेम्पलेट्स कई तत्कालताओं के माध्यम से संकलित समय पॉलीमोर्फिक कंटेनर (साथ ही टेम्पलेट मेटाप्रोग्रामिंग को C++ प्रकार प्रणाली पर एक (वर्तमान में कमजोर टाइप की गई) भाषा प्रदान करके अनुमति देता है।)। यह दिए गए प्रकारों के लिए विशेषज्ञता के लिए अनुमति देता है, एक से अधिक संकलित तत्कालता की आवश्यकता से डाउनसाइड संभावित "कोड ब्लोट" हो रहा है।

टेम्पलेट जेनरिक से अधिक शक्तिशाली हैं; पूर्व प्रभावी रूप से सी ++ के भीतर एम्बेडेड एक और भाषा है, जबकि मेरे ज्ञान का सबसे अच्छा है, उत्तरार्द्ध केवल कंटेनरों में उपयोगी है

+0

[बोल्ट कार्य] (https://github.com/ बोल्ट्स फ्रेमवर्क/बोल्ट्स- एंड्रॉइड) जेनरिकों के कंटेनरों के बाहर उपयोगी होने का एक दिलचस्प उदाहरण है। – Pablo

1

आप जीएनयू ट्रोव से TIntArraList को आजमा सकते हैं जो int मूल्यों के ऐरेलिस्ट की तरह कार्य करेगा।

1

मुख्य अंतर जिस तरह से लागू किया गया है, लेकिन उनके नाम सटीक रूप से उनके कार्यान्वयन का वर्णन करते हैं।

टेम्पलेट्स टेम्पलेट्स की तरह व्यवहार करते हैं। इसलिए, यदि आप लिखना: प्रत्येक प्रकार के जो कॉल करने के लिए f एक नया कोड है प्रयोग किया जाता है के लिए

void f_generated_with_int(int s) 
{ 
    std::cout << s << '\n'; 
} 

... 
int x = 0; 
f_generated_with_int(x); 
... 

तो,: तो अंत संकलक में की तरह व्यवहार करता है कोड

template<typename T> 
void f(T s) 
{ 
    std::cout << s << '\n'; 
} 

... 
int x = 0; 
f(x); 
... 

संकलक टेम्पलेट लागू होता है, "उत्पन्न"।

दूसरी तरफ, जेनेरिक केवल टाइप चेक किया जाता है, लेकिन फिर सभी प्रकार की जानकारी मिटा दी जाती है। इसलिए, यदि आप लिखना:

class X<T> { 
    private T x; 

    public T getX() { return x; } 
    public void setX(T x) { this.x = x; } 
} 

... 
Foo foo = new Foo(); 
X<Foo> x = new X<>(); 
x.setX(foo); 
foo = x.getX(); 
... 

जावा इसे पसंद संकलित:

class X { 
    private Object x; 

    public Object getX() { return x; } 
    public void setX(Object x) { this.x = x; } 
} 

... 
Foo foo = new Foo(); 
X x = new X(); 
x.setX(foo); 
foo = (Foo)x.getX(); 
... 

अंत में:

  • टेम्पलेट्स टेम्प्लेटेड समारोह (प्रत्येक के संकलन में की गई प्रत्येक कॉल की इन्स्टेन्शियशन आवश्यकता होती है। सीपीपी फ़ाइल), इसलिए जनरेट्स के साथ
  • संकलित करने के लिए टेम्पलेट धीमे हैं, आप प्राइमेटिव्स का उपयोग नहीं कर सकते हैं, क्योंकि वे Object नहीं हैं, इसलिए जेनेरिक कम विपरीत है टाइल
संबंधित मुद्दे