2016-12-25 20 views
6

समृद्ध प्रोफाइलिंग के कारण, हमारे जावा कोड को शून्य वस्तुओं के विधि परिणामों के आउटपुट के साथ अव्यवस्थित किया गया है।जावा 8 विधि संदर्भ का उपयोग कर नलचेक विधि संभव है?

यह इस

namedObject == null ? "?" : namedObject.getName() 

तरह लग रहा है यह संभव है इस के लिए एक स्थिर विधि लिखने के लिए? (उदाहरण के लिए इस तरह दिख रहा है):

Util.nvl(namedObject, NamedObject::getName, "?") 

= Util.nvl जैसा दिखता है? मैंने थोड़ा खोजा गया Google प्रयोग किया है लेकिन कोई परिणाम नहीं मिला है।

यह काम नहीं करता:

public static <T> T nvl(T value, Function<T, ?> method, T nullSubstition) { 
    return value == null ? nullSubstition : (T) method.apply(value); 
} 

संकलक मुझसे कहता है: गैर स्थैतिक विधि getName() एक स्थिर संदर्भ

उत्तर

8

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

आप दो सामान्य प्रकार पैरामीटर की जरूरत है:

public class Utils { 

    public static <O, T> T nvl(O value, Function<O, T> method, T nullSubstition) { 
     return value == null ? nullSubstition : method.apply(value); 
    } 

    static class NamedObject { 
     String getName() { 
      return "foo"; 
     } 
    } 

    public static void main(String[] args) { 
     NamedObject foo = null; 
     String name = Utils.nvl(foo, NamedObject::getName, "bar"); 
     System.out.println("name = " + name); // name = bar 

     foo = new NamedObject(); 
     name = Utils.nvl(foo, NamedObject::getName, "bar"); 
     System.out.println("name = " + name); // name = foo 
    } 
} 

इससे भी बेहतर हस्ताक्षर, और अधिक लचीलापन अनुमति देता है,

public static <O, T> T nvl(O value, Function<? super O, ? extends T> method, T nullSubstition) { 
    return value == null ? nullSubstition : method.apply(value); 
} 
+1

शानदार उत्तर, बहुत बहुत धन्यवाद! – Nachaz

+0

यह एक "nvl" ऑपरेशन नहीं है, हालांकि, यह "getOrDefault" ऑपरेशन है। –

5

आपका विधि के जेनरिक सही ढंग से परिभाषित नहीं कर रहे हैं होगा। आप एक विधि बनाने का प्रयास कर रहे हैं जो किसी विशेष प्रकार की वस्तु (T, तर्क के लिए, या NamedObject दिए गए उदाहरण में) प्राप्त करता है, और एक विधि लागू करता है जो तर्क के लिए एक अलग प्रकार (S) का ऑब्जेक्ट देता है

public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) { 
    return value == null ? nullSubstition : (S) method.apply(value); 
} 

ध्यान दें कि जावा 8 के Optional आप एक और अधिक सुरुचिपूर्ण तरीके से इस लिखने के लिए अनुमति दे सकता है (हालांकि शान में कुछ हद तक है:, या दिए गए उदाहरण में String), या एक डिफ़ॉल्ट S मूल्य अगर पारित वस्तु null है दर्शक की आंख):

public static <T, S> S nvl(T value, Function<T, S> method, S nullSubstition) { 
    return Optional.ofNullable(value).map(method).orElse(nullSubstition); 
} 
+1

का मतलब है 'वैकल्पिक .ofNullable()' सही? –

+1

@ पैट्रिकपाकर हां। अपने आप से आगे निकल गया :-) संपादित और तय, ध्यान देने के लिए धन्यवाद! – Mureinik

+2

अच्छा उदाहरण। हो सकता है कि इस फ़ंक्शन के लिए एक अच्छा नाम 'वैकल्पिकMapOrElse' होगा, क्योंकि यह उस नोटेशन के लिए शॉर्टेंड है। –

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