2016-12-25 9 views
6

Из-за богатого профилирования наш код Java загроможден выводами результатов метода объектов с нулевым значением.Nullcheck способ используя java8 способ ссылка возможно?

Похоже, что этот

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 в качестве первого аргумента (так что T является NamedObject) и возвращает String (так что теперь T является String).

Вам необходимы два параметров универсального типа:

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, ради аргумента или String в данном примере), или значение по умолчанию S, если передаваемый объект null:

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

Обратите внимание, что Java 8-х Optional может позволить вам записать это более элегантно (хотя элегантность в некоторой степени глаз наблюдателя):

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

Вы имеете в виду 'Optional.ofNullable()' right? –

+1

@PatrickParker да. Поймал себя там :-) Отредактировано и исправлено, спасибо, что заметили! – Mureinik

+2

хороший пример. возможно, хорошим именем для этой функции будет 'optionalMapOrElse', поскольку это сокращение для этой нотации. –