2009-11-05 8 views
6

क्या कोई मुझे बता सकता है कि निम्न कोड क्यों काम नहीं करता है?जेनेरिक त्रुटि: तर्कों के लिए लागू नहीं

public class Test { 

interface Strategy<T> { 
    void execute(T t); 
} 

public static class DefaultStrategy<T> implements Strategy<T> { 
    @Override 
    public void execute(T t) {} 
} 

public static class Client { 
    private Strategy<?> a; 

    public void setStrategy(Strategy<?> a) { 
    this.a = a; 
    } 

    private void run() { 
    a.execute("hello world"); 
    } 
} 

public static void main(String[] args) { 
    Client client = new Client(); 
    client.setStrategy(new DefaultStrategy<String>()); 
    client.run(); 
} 
} 

मैं निम्न त्रुटि हो रही है:

The method execute(capture#3-of ?) in the type Test.Strategy<capture#3-of ?> 
is not applicable for the arguments (String) 

मैं कोड को बदलकर काम करने के लिए मिल गया इस प्रकार है:

public class Test { 

interface Strategy<T> { 
    void execute(T t); 
} 

public static class DefaultStrategy<T> implements Strategy<T> { 
    @Override 
    public void execute(T t) {} 

} 

public static class Client<T> { 
    private Strategy<T> a; 

    public void setStrategy(Strategy<T> a) { 
    this.a = a; 
    } 

    private void run(T t) { 
    a.execute(t); 
    } 
} 

public static void main(String[] args) { 
    Client<String> client = new Client<String>(); 
    client.setStrategy(new DefaultStrategy<String>()); 
    client.run("hello world"); 
} 
} 

लेकिन मैं क्यों मूल को समझना चाहते हैं दृष्टिकोण काम नहीं किया।

उत्तर

0

ऐसा इसलिए है क्योंकि अपनी कक्षा Client कोई विशेष Strategy (Strategy<?>) के लिए लिखा है काम नहीं करता है, लेकिन run() विधि में, आप पारित एक String (जो केवल Strategy<String> के लिए सही है!)। यह केवल तभी काम करेगा यदि आप a के प्रकार और setStrategy() के पैरामीटर Strategy<String> पर बदल देंगे!

11

उत्तर सरल है: अनबाउंड वाइल्डकार्ड का उपयोग नहीं किया जा सकता है। इसका मतलब है "uknown ऑब्जेक्ट"।

यह कंपाइलर को कुछ भी जानकारी नहीं देता है। "?" जो भी प्रकार का मतलब है, तो वास्तव में यह कुछ भी मतलब सामान्य है। http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html

के रूप में कहा गया है:

Collection<?> c = new ArrayList<String>(); 
c.add(new Object()); // Compile time error 

के बाद से हम नहीं जानते कि क्या ग के तत्व प्रकार के लिए खड़ा है, हम नहीं वस्तुओं इसे करने के लिए जोड़ सकते हैं

यहाँ एक नजर डालें। ऐड() विधि प्रकार ई, संग्रह के तत्व प्रकार के तर्क लेती है। जब वास्तविक प्रकार पैरामीटर होता है, तो यह किसी अज्ञात प्रकार के लिए खड़ा होता है। हमारे द्वारा जोड़े जाने वाले किसी भी पैरामीटर को इस अज्ञात प्रकार का उप-प्रकार होना चाहिए। चूंकि हम नहीं जानते कि यह किस प्रकार का है, हम कुछ भी पास नहीं कर सकते हैं। एकमात्र अपवाद शून्य है, जो हर प्रकार का सदस्य है।

संपादित करें: चिंता न करें, जब आप उनका उपयोग शुरू करते हैं तो यह जावा वाइल्डकार्ड की सामान्य गलतफहमी है। यही कारण है कि वाइल्डकार्ड बाध्य (उदाहरण के लिए <? extends Something>) मौजूद है, अन्यथा जेनेरिक वाइल्डकार्ड लगभग बेकार होगा क्योंकि संकलक इस पर कोई धारणा नहीं कर सकता है।

0

ऐसा इसलिए है क्योंकि यह एक प्रकार का सुरक्षित संचालन नहीं है। "?" एक वाइल्डकार्ड है जिसका मतलब है कि मुझे इस प्रकार का पता नहीं है। इसका मतलब "किसी भी प्रकार" नहीं है। इसे पढ़ें ... http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

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