2009-03-29 17 views
7

मैं एक समारोह पर ठोकर खाई इस तरह लग रही:<?> बनाम <T>

public void function(Class<?> clazz) {...} 

क्या पेशेवरों/करने के लिए विधि बदलने की विपक्ष की जाती हैं:

public <T> void function(Class<T> clazz) {...} 

संपादित करें: क्या संकलन समय/क्रम हैं diff।

उत्तर

7

todd.run पूरी तरह से सही है, लेकिन यह केवल आधा जवाब है। <T><?> (या इसके विपरीत) पर <T> चुनने के लिए भी उपयोग के मामले हैं जो लागू होते हैं जब आप विधि को संलग्न करने वाले वर्ग में टाइप पैरामीटर नहीं जोड़ते हैं। उदाहरण के लिए, वास्तव में संकलन नहीं होगा

public <E extends JLabel> boolean add(List<E> j) { 
    boolean t = true; 
    for (JLabel b : j) { 
     if (b instanceof JLabel) { 
      t = t && labels.add(b); 
     } 
    } 
    return t; 
} 

और

public boolean add(List<? extends JLabel> j) { 
    boolean t = true; 
    for (JLabel b : j) { 
     if (b instanceof JLabel) { 
      t = t && labels.add(b); 
     } 
    } 
    return t; 
} 

पहली विधि के बीच अंतर पर विचार जब तक आप, संलग्नित क्लास के लिए एक उपयुक्त प्रकार पैरामीटर जोड़ने जबकि दूसरी विधि चाहे संकलन होगा संलग्न वर्ग में एक प्रकार पैरामीटर है। यदि आप <?> का उपयोग नहीं करते हैं, तो आप संकलक को यह कहने के लिए स्थानीय रूप से ज़िम्मेदार हैं कि उस प्रकार का अधिग्रहण कैसे किया जाए जो उसके स्थान पर उपयोग किए गए पत्र द्वारा भरा जाएगा। आप अक्सर इस समस्या का सामना करते हैं - उपयोग करने की आवश्यकता है? टी के बजाय - जेनेरिक विधियों को लिखने का प्रयास करते समय "विस्तार" और "सुपर" की आवश्यकता होती है। इस मुद्दे का एक बेहतर लेकिन अधिक विस्तृत उपचार Gilad Bracha's Generics Tutorial (PDF) के पृष्ठ 18 पर है। this stack overflow question भी देखें जिसका उत्तर इन मुद्दों को प्रकाशित करता है।

अपने दूसरे प्रश्न के बारे में जानकारी के लिए इस स्टैक ओवरफ़्लो लिंक को देखें: Java generics - type erasure - when and what happens। जबकि मुझे <?> और <T> के बीच संकलन समय अंतर के बारे में आपके प्रश्न का उत्तर नहीं पता है, मुझे पूरा यकीन है कि उत्तर उस पोस्ट में उल्लिखित एरिक्सन this FAQ पर पाया जा सकता है।

+0

आप इस मामले में वाइल्डकार्ड प्रकार को कैप्चर कर सकते हैं: बूलियन ऐड (सूची सूची बढ़ाती है) {वापसी addImpl (सूची); } <टी JLabel> बूलियन addImpl (सूची सूची) को विस्तारित करता है {... –

+0

(उदाहरण कोड थोड़ा अजीब है। आप लेबल्स के बाद वापस आ सकते हैं। मैड झूठ देता है। –

+0

यह उत्तर समझ में नहीं आता है और यह सही नहीं है। मैंने बिना किसी प्रकार के पैरामीटर ('पब्लिक क्लास टेस्ट {सूची लेबल्स = नई ऐरेलिस्ट (); // ऐड विधि}} के बिना पहली विधि को कक्षा में रखा है और यह ठीक संकलित करता है। – user102008

2

असल में, वे बराबर हैं। आप पहले वाक्यविन्यास का उपयोग कर सकते हैं जहां आपको किसी भी प्रकार की टी/

अद्यतन: ओह, और टी का उपयोग प्रकारों को एक साथ बांधने के लिए किया जा सकता है: यदि Class<T> फ़ंक्शन के विभिन्न हिस्सों में उपयोग किया जाता है एक ही कक्षा में, लेकिन Class<?> नहीं।

+0

हालांकि, कि नहीं स्थितियों में, जहां एक विधि हस्ताक्षर में / के कई आवृत्तियां देखते हैं में सही है। – dmeister

+0

नहीं।इस मामले में एक विधि-विशिष्ट प्रकार पैरामीटर है, इसलिए यह कक्षा के स्तर पर उपयोग किए जाने वाले समान प्रकार का संदर्भ नहीं देगा, भले ही इसे टी भी कहा जाता है। –

+0

@ सोआ: कक्षा स्तर –

10

"?" का उपयोग करना "किसी भी" जैसा ही है, जबकि "टी" का अर्थ है "एक विशिष्ट प्रकार"। तो, इन इंटरफेस की तुलना: अब

public interface StrictClass<T> { 
public T doFunction(Class<T> class); 
} 

public interface EasyClass<T> { 
public > doFunction(Class<?> class); 
} 

, हम कक्षाओं बना सकते हैं:

public class MyStrictClass implements StrictClass<String> { 
    public String doFunction(Class<String> stringClass) { 
    //do something here that returns String 
    } 
} 

public class MyEasyClass implements EasyClass<String> { 
    public String doFunction(Class<?> anyClass) { 
    //do something here that returns String 
    } 
} 

आशा है कि मदद करता है!

+0

"सार्वजनिक डूफंक्शन" के बारे में कोई भी बात नहीं कर रहा है और गलत भी नहीं होना चाहिए। मुझे लगता है कि आप इसे "सार्वजनिक टी DoFunction" होने का मतलब था। –

+0

इसके अलावा, "कक्षा" को एक चर नाम के रूप में उपयोग नहीं किया जा सकता है, क्योंकि यह एक आरक्षित शब्द है। –

0

एक अच्छा संसाधन यह हो सकता है: http://sites.google.com/site/io/effective-java-reloaded आपके प्रश्न से संबंधित दिलचस्प हिस्सा 5 वें मिनट के आसपास शुरू होता है। पिछले उपयोगकर्ताओं ने जो कहा वह सिर्फ व्यसन में।

आशा है कि मदद करता है:]

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