2012-06-18 6 views
45

क्या जावा में Callable इंटरफ़ेस जैसा कोई इंटरफ़ेस है, जो इसकी कॉल विधि के लिए एक तर्क स्वीकार कर सकता है?क्या कॉल करने योग्य के समान इंटरफ़ेस है लेकिन तर्क के साथ?

तो जैसा

:

public interface MyCallable<V> { 
    V call(String s) throws Exception; 
} 

मैं नहीं बल्कि अगर वहाँ पहले से ही कुछ ऐसा है जो मैं उपयोग कर सकते हैं मौजूद है एक नए प्रकार बनाने से बचना होगा। या क्या कई क्लाइंट लागू करने और कॉल करने योग्य दिनचर्या में प्लग करने की बेहतर रणनीति है?

यहाँ http://www.programmingforums.org/thread27905.html

+1

नहीं, लेकिन http://www.programmingforums.org/thread27905.html जैसी चीजों को देखने। –

उत्तर

31

जावा 8 के बाद से से कॉपी किया गया the java.util.function package में समारोह की तरह इंटरफेस के एक पूरे सेट है। जिसे आप विशेष रूप से पूछ रहे हैं वह केवल Function है।

जावा 8 से पहले, इसके लिए कोई सामान्य उद्देश्य, अंतर्निहित इंटरफ़ेस नहीं था, लेकिन कुछ पुस्तकालयों ने इसे प्रदान किया।

उदाहरण के लिए Guava विधि के साथ the Function<F,T> interface है। यह कई स्थानों पर heavy use of that interface बनाता है।

+0

यह वही प्रश्न पिछले हफ्ते मेरे सहकर्मियों के लिए हुआ था।हमारी पहली और स्पष्ट पसंद Guava से फंक्शन का उपयोग करना था। हालांकि हमने देखा कि आवेदन() विधि अपवाद नहीं फेंक दिया। इसने हमारे उद्देश्यों के लिए अनुपयुक्त प्रदान किया। दुर्भाग्यवश, हमें इसके लिए अपना इंटरफ़ेस बनाना समाप्त करना पड़ा। कम से कम यह एक कंपनी के व्यापक lib में मिला, फिर से इस्तेमाल किया जा सकता है। –

+1

@ फिलिपफेडल्टो: ठीक है, दोनों अपवाद-फेंकने और गैर-फेंकने 'फंक्शन' उपयोगी हो सकते हैं। गुवा में 'फंक्शन' के अधिकांश उपयोग सरल हैं "ए-टू-बी" और "बार ऑब्जेक्ट से फू प्राप्त करें" का उपयोग करना चाहिए जो कभी भी (एक सेन प्रोग्राम में) एक चेक अपवाद फेंकना नहीं चाहिए (एनपीई और अनचेक वाले लोग एक अलग कहानी हैं)। यह है (शायद) क्यों गुवा 'फंक्शन' अपवाद नहीं फेंकता है। –

+0

आप इसके साथ _do_ करने का प्रयास कर रहे हैं? इस तरह का एक इंटरफ़ेस केवल तभी उपयोगी होता है जब इसे लागू करने से आप प्रत्यक्ष कार्यान्वयन के साथ चीजों को बेहतर तरीके से कर सकते हैं। यह 'फंक्शन' के साथ हमेशा सत्य नहीं होता है, अकेले अधिक जटिल जानवरों को छोड़ दें। –

1

उत्तर संदिग्ध है। कड़ाई से बोलते हुए, "कॉल करने योग्य इंटरफेस के उसी उद्देश्य के लिए" है, ऐसा नहीं है।

समान वर्ग हैं, और आप जो चाहते हैं उसके आधार पर, वे सुविधाजनक हो सकते हैं या नहीं भी हो सकते हैं। उनमें से एक SwingWorker है। हालांकि, जैसा कि नाम का तात्पर्य है, इसे स्विंग ढांचे के भीतर उपयोग के लिए डिज़ाइन किया गया था। इसका इस्तेमाल अन्य उद्देश्यों के लिए किया जा सकता है, लेकिन यह एक खराब डिजाइन विकल्प होगा।

मेरी सबसे अच्छी सलाह है कि आप अपने सिस्टम में पहले से उपयोग की जाने वाली पुस्तकालयों के आधार पर एक्सटेंशन लाइब्रेरी (जकार्ता-कॉमन्स, गुवा, और इसी तरह) द्वारा प्रदान किए गए एक का उपयोग करें।

0

आम तौर पर तर्कों की आवश्यकता नहीं होती है क्योंकि इस विधि में इसके निर्माता में कोई भी तर्क हो सकता है।

final int i = 5; 
final String word = "hello"; 

Future<String> future = service.submit(new Callable<String>() { 
    public String call() { 
     return word + i; 
    } 
}); 

इस उदाहरण i में और word इस्तेमाल किया गया है, लेकिन आप "पारित" पैरामीटर के किसी भी संख्या कर सकते हैं।

+0

असल में आप सही हैं, लेकिन कई बिंदुओं से विस्तारित करने के लिए, प्रत्येक बार नए कॉल करने योग्य ऑब्जेक्ट को ओवरहेड और बेकार हो सकता है। उदाहरण - फिर आप एकल तत्व द्वारा एक से अधिक संग्रह को संसाधित करते हैं, एक-एक करके, या जब आपके पास कुछ घटक होता है और आपको उसे डिलीवरी प्रक्रिया (मिश्रण/गड़बड़ तर्क से बचने के लिए) चाहिए। – iMysak

+0

@iMysak एक कतार के माध्यम से धागे के बीच काम पास करने के लिए आप कुछ वस्तुओं (कम से कम 3 मुझे संदेह) बनाने के लिए जा रहे हैं –

+0

वास्तव में, इस बिंदु से आप पूरी तरह से सही हैं :) – iMysak

7

पहले यह सोचा कि यह एक इंटरफ़ेस के साथ किया गया है लेकिन फिर मुझे पता चला कि यह एक अमूर्त वर्ग का उपयोग करके किया जाना चाहिए।

मैं इसे इस तरह से हल कर लिया है:


संपादित करें: हाल ही में मैं सिर्फ इस का उपयोग करें:

public static abstract class callback1<T>{ 
     public abstract void run(T value); 
    } 

    public static abstract class callback2<T,J>{ 
     public abstract void run(T value,J value2); 
    } 

    public static abstract class callback3<T,J,Z>{ 
     public abstract void run(T value,J value2,Z value3); 
    } 


    public static abstract class callbackret1<R,T>{ 
     public abstract R run(T value); 
    } 

    public static abstract class callbackret2<R,T,J>{ 
     public abstract R run(T value,J value2); 
    } 

    public static abstract class callbackret3<R,T,J,Z>{ 
     public abstract R run(T value,J value2,Z value3); 
    } 

कॉलबैक।जावा

public abstract class CallBack<TRet,TArg> { 
    public abstract TRet call(TArg val); 
} 

परिभाषित विधि:

class Sample2 
{ 
    CallBack<Void,String> cb; 
    void callcb(CallBack<Void,String> CB) 
    { 
    cb=CB; //save the callback 
    cb.call("yes!"); // call the callback 
    } 
} 

उपयोग विधि:

sample2.callcb(new CallBack<Void,String>(){ 
     @Override 
     public Void call(String val) { 
      // TODO Auto-generated method stub 
      return null; 
     } 
    }); 

दो तर्क नमूना: CallBack2.java

public abstract class CallBack2<TRet,TArg1,TArg2> { 
    public abstract TRet call(TArg1 val1,TArg2 val2); 
} 

ध्यान दें कि जब आप शून्य रिटर्न प्रकार का उपयोग करते हैं तो आपको रिटर्न नल का उपयोग करना होगा; तो यहां इसे ठीक करने के लिए एक भिन्नता है क्योंकि आमतौर पर कॉलबैक किसी भी मूल्य को वापस नहीं करते हैं। वापसी प्रकार के रूप में

शून्य: SimpleCallBack.java

public abstract class SimpleCallBack<TArg> { 
    public abstract void call(TArg val); 
} 

वापसी प्रकार 2 args के रूप में शून्य: SimpleCallBack2.java

public abstract class SimpleCallBack<TArg1,TArg2> { 
    public abstract void call(TArg1 val1,TArg2 val2); 
} 

इंटरफ़ेस इस के लिए उपयोगी नहीं है।

इंटरफेस कई प्रकार के मिलान समान प्रकार की अनुमति देता है। कार्यों के एक पूर्वनिर्धारित सेट साझा करके।

अमूर्त वर्ग बाद में पूरा होने के लिए खाली कार्यों को अनुमति देते हैं। विस्तार या तत्काल पर।

+0

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

+0

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

+0

कास्टिंग करने की आवश्यकता नहीं है, मुझे अभी भी एक अमूर्त वर्ग का उपयोग करने का लाभ नहीं दिख रहा है: वे सबसे उपयोगी होते हैं जब उप-वर्गों में स्केलेट के साथ लागू किए जाने वाले तरीकों को प्रदान करने के लिए उपयोग किया जाता है कार्यान्वयन जो उप-वर्गों के विकास को आसान बनाता है। यहां आपके सार वर्गों में केवल कोई कोड नहीं है, केवल अमूर्त तरीकों। इसलिए, आप इसके बजाय इंटरफेस का उपयोग कर सकते हैं। –

4

मुझे हाल ही में एक ही आवश्यकता है। जैसा कि अन्य ने समझाया है कि कई libs 'कार्यात्मक' विधियां प्रदान करते हैं, लेकिन ये अपवाद नहीं फेंकते हैं।

कैसे कुछ परियोजनाओं के लिए एक समाधान प्रदान की है का एक उदाहरण RxJava पुस्तकालय जहां वे ActionX जहां 'एक्स' 0 है ... एन, कॉल विधि करने के लिए तर्क की संख्या में इस तरह के रूप में इंटरफेस का उपयोग करें । उनके पास एक varargs इंटरफ़ेस भी है, एक्शनएन

मेरे वर्तमान दृष्टिकोण एक सरल सामान्य इंटरफ़ेस का उपयोग करने के लिए है:

public interface Invoke<T,V> {  
    public T call(V data) throws Exception;  
// public T call(V... data) throws Exception;  
} 

दूसरी विधि मेरे मामले में बेहतर है, लेकिन यह दर्शाती है कि खतरनाक "प्रकार की सुरक्षा: के माध्यम से संभावित ढेर प्रदूषण पैरामीटर डेटा varargs" मेरे आईडीई में , और यह एक अन्य मुद्दा है।

एक और दृष्टिकोण मैं देख रहा हूँ इस तरह के रूप java.util.concurrent.Callable मौजूदा इंटरफेस है कि अपवाद और फेंक नहीं है, अनियंत्रित अपवाद में मेरी कार्यान्वयन रैप अपवादों में उपयोग करने के लिए है।

0

मुझे बस एक ही समस्या थी। आप किसी कॉल करने योग्य को वापस करने के लिए किसी भी विधि को लपेट सकते हैं, और उसके लौटाए गए मान को निष्पादित कर सकते हैं। अर्थात

main {  
    Callable<Integer> integerCallable = getIntegerCallable(400); 
    Future<Integer> future = executor.submit(integerCallable); 
} 

private Callable<Integer> getIntegerCallable(int n) { 
    return() -> { 
      try { 
       TimeUnit.SECONDS.sleep(n); 
       return 123; 
      } catch (InterruptedException e) { 
       throw new IllegalStateException("task interrupted", e); 
      } 
     }; 
} 
संबंधित मुद्दे