2016-12-25 19 views
6

Dzięki bogatemu profilowaniu nasz kod Java jest zagracony z wynikami wyników metod obiektów zerowych.Metoda Nullcheck przy użyciu odwołania do metody java8 możliwe?

Wygląda to

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

jest to możliwe, aby napisać statycznej metody na to? (np. wyglądając w ten sposób):

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

Jak wyglądałby Util.nvl? Eksperymentowałem trochę z wyszukiwanym Google, ale nie uzyskałem żadnego wyniku.

To nie działa:

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

Kompilator mówi mi: niestatyczny metoda getName() nie można odwoływać się od statycznego kontekście

Odpowiedz

8

Twój podpis nie może być prawidłowa. Chcesz, aby twoja metoda wzięła NamedObject jako pierwszy argument (tak, że T jest NamedObject) i zwróciła String (więc teraz T jest String).

Potrzebne są dwa ogólne parametry Typ:

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 
    } 
} 

jeszcze lepszy podpisu, co pozwala na większą elastyczność, byłoby

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

Znakomita odpowiedź, wielkie dzięki! – Nachaz

+0

Nie jest to operacja "nvl", ale jest to operacja "getOrDefault". –

5

rodzajowych metodę nie są określone prawidłowo. Próbujesz utworzyć metodę, która odbiera obiekt określonego typu (T, z uwagi na argument, lub NamedObject w podanym przykładzie) i stosuje metodę, która zwraca obiekt innego typu (S, dla argumentu lub String w podanym przykładzie) lub wartość domyślna S jeśli przekazany obiekt jest null:

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

Zauważ, że Java 8 na Optional może pozwolić Ci napisać to w bardziej elegancki sposób (choć elegancja jest nieco w oko patrzącego):

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

masz na myśli 'Optional.ofNewble()', prawda? –

+1

@PatrickParker tak. Wystartowałem tam :-) Zmieniono i poprawiono, dzięki za uwagę! – Mureinik

+2

ładny przykład. może dobrym nazwiskiem dla tej funkcji będzie "optionalMapOrElse", ponieważ jest skrótem dla tej notacji. –

Powiązane problemy