2012-10-10 15 views
9

निम्नलिखित इंटरफेस को देखते हुए में जेनेरिक इंटरफ़ेस को लागू जावा,एक अनाम वर्ग

public interface Callback<T> { 
    <K, V> T execute(Operation<K, V> operation) throws SomeException; 
} 

मैं एक नई अज्ञात वर्ग जहां operation प्रकार की है में इंटरफ़ेस कैसे लागू होगा Operation<String,String>

जैसे, यह नहीं है संकलन:

Callback<Boolean> callback = new Callback<Boolean>() { 
     @Override 
     public Boolean execute(Operation<String, String> operation) { 
       return true; 
     } 
}; 
executor.execute(callback); 
+1

क्या संकलन त्रुटि नहीं आप मिलता है बुला कि execute(Callback<?>) विधि हो जाएगा कर सकते हैं? मैं देख सकता हूं कि आपके फ़ंक्शन में रिटर्न स्टेटमेंट नहीं है, जो एक संकलन त्रुटि है। –

+1

संकलन त्रुटि का कारण क्या है? और 'कुछ अपवाद' कहां है? – mishadoff

+2

मेरा सुझाव है कि आप किसी भी सामान्य वर्ग या इंटरफ़ेस का नाम दोबारा उपयोग न करें और इसके बजाय एक अलग नाम का उपयोग करें। नामों का पुन: उपयोग करने से आपके जैसे भ्रम पैदा होते हैं। –

उत्तर

7

पद्धति पर जेनरिक वर्ग से संबंधित नहीं सामान्य मापदंडों

आप इसे सही होने के लिए के लिए, उदाहरण के लिए विधि पर उन्हें दोहराने की जरूरत है

Callback<Boolean> callback = new Callback<Boolean>() { 
     @Override 
     public <X,Y> Boolean execute(Operation<X, Y> operation) { 

     } 
}; 
executor.execute(callback); 

दूसरे शब्दों में इंटरफ़ेस को निष्पादन विधि की आवश्यकता होती है जो किसी भी ऑपरेशन पैरामीटर पर काम करता है।

यदि आप एक कॉलबैक चाहते हैं जो केवल विशिष्ट मानकों पर काम करता है तो आपको उन्हें कक्षा हस्ताक्षर का हिस्सा बनाने की आवश्यकता होती है, उदा।

public interface Callback<T,K,V> { 
    T execute(Operation<K, V> operation) throws SomeException; 
} 

है कि तब दिया जाएगा आप

Callback<Boolean,String,String> callback = new Callback<Boolean,String,String>() { 
     @Override 
     public Boolean execute(Operation<String, String> operation) { 

     } 
}; 
executor.execute(callback); 

कर मैं आप क्या चाहते हैं ... जब तक आप <? super K,? super V> या <? extends K,? extends V> रूपों जो आप बहुत ज्यादा सीमित कर सकते हैं का उपयोग शुरू हो रही है के लिए एक मार्ग नहीं देख सकता।

गया है कि आपकी इंटरफ़ेस

public interface Callback<T> { 
    T execute(Operation<Object, Object> operation) throws SomeException; 
} 

को मिटा देता है फिर जब आप T == Boolean साथ दृष्टांत हम

public interface Callback { 
    Boolean execute(Operation<Object, Object> operation) throws SomeException; 
} 

में के रूप में एक

Boolean execute(Operation<String, String> operation) throws SomeException; 

विधि से लागू नहीं किया जा सकता है जो मिलता है पैरामीटर संकुचित हैं। आप पैरामीटर में विस्तार कर सकते हैं और पैरामीटर को संकुचित कर सकते हैं लेकिन आप दूसरी तरफ नहीं जा सकते हैं।

बताते हैं यही कारण है कि आप एक Object उम्मीद कर एक Boolean साथ खुश हो जाएगा किसी को भी Boolean करने के लिए (बाहर पैरामीटर) Object से वापसी प्रकार बदल सकते हैं।

इसके विपरीत हम रिटर्न प्रकार को विस्तृत नहीं कर सकते हैं क्योंकि यह विधि को कॉल करने और परिणाम पर कार्य करने वाले किसी को भी ClassCastException देगा।

विधि तर्क (पैरामीटर में) केवल विस्तृत किया जा सकता है। अब यह विधि तर्क के लिए कुछ जटिल है के रूप में जावा विभिन्न तरीकों के रूप में विभिन्न प्रकार देखता है, तो आप कानूनी तौर पर

public interface Callback<T> { 
    T execute(Object key, Object value); 
} 

Callback<Boolean> cb = new Callback<Boolean> { 
    @Override 
    public Boolean execute(Object k, Object v) { ... } 
    // not an @Override 
    public Boolean execute(String k, String v) { ... } 
} 

क्योंकि दूसरी विधि एक अलग हस्ताक्षर हैं हो सकता है।लेकिन अपने Operation<X,Y> वर्ग यह है चाहे बस कच्चे प्रकार के मिट जाता है एक Operation<String,String> या Operation<X,Y>

एक बात तुम कर सकते हो ... नहीं है, लेकिन यह गंदा हो जाता है!

public interface StringOperation extends Operation<String,String> {} 

तो आप

Callback<Boolean> cb = new Callback<Boolean> { 
    @Override 
    public <K,V> Boolean execute(Operation<K,V> o) { ... } 
    // not an @Override 
    public Boolean execute(StringOperation o) { ... } 
} 

करते लेकिन ध्यान रखें <K,V> Boolean execute(Operation<K,V> o) और Boolean execute(StringOperation o)

5

क्योंकि आपके वर्ग के नाम में प्रकार पैरामीटर और विधि में प्रकार पैरामीटर वास्तव में अलग है आप कर सकते हैं नीचे।

@Override 
    public <K, V> Boolean execute(Operation<K, V> operation) 
      throws SomeException { 
     return false; 
    } 
+0

यह काम करता है, लेकिन अगर मैं स्पष्ट रूप से सामान्य प्रकार <स्ट्रिंग, स्ट्रिंग> पक्ष निष्पादन विधि में उपयोग करने के लिए ऑपरेशन चाहता हूं तो क्या होगा? – user1735096

+0

आपको कॉलबैक 'को कॉलबैक ' –

+0

धन्यवाद 'में बदलना होगा। दुर्भाग्यवश इस मामले में, यह एक इंटरफ़ेस नहीं था जिसे मैं नियंत्रित करता हूं। – user1735096

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