2016-12-25 2 views
6

En raison du profilage riche, notre code Java est encombré avec des sorties de résultats de méthode d'objets Nullable.Méthode Nullcheck utilisant la référence de méthode java8 possible?

Il ressemble à ce

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

est-il possible d'écrire une méthode statique pour cela? (par exemple ressemblant à ceci):

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

À quoi ressemblerait = Util.nvl? J'ai expérimenté un peu google recherché mais n'ai donné aucun résultat.

Cela ne fonctionne pas:

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

Le compilateur me dit: getName() non statique ne peut pas être référencé à partir d'un contexte statique

Répondre

8

Votre signature ne peut pas être correct. Vous voulez que votre méthode prenne le NamedObject comme premier argument (donc T est un NamedObject), et renvoyer une String (maintenant T est String).

Vous avez besoin de deux paramètres de type générique:

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

encore mieux la signature, ce qui permet une plus grande flexibilité, serait

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

Superbe réponse, merci beaucoup! – Nachaz

+0

Ce n'est pas une opération "nvl", cependant, c'est une opération "getOrDefault". –

5

les génériques de votre méthode ne sont pas définis correctement. Vous tentez de créer une méthode qui reçoit un objet d'un certain type (T, par exemple, ou un NamedObject dans l'exemple donné) et applique une méthode qui renvoie un objet d'un type différent (S, par exemple) ou String dans l'exemple donné), ou un défaut S valeur si l'objet passé est null:

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

Notez que Java 8 de Optional peut vous permettre d'écrire ceci d'une manière plus élégante (bien que l'élégance est quelque peu l'œil du spectateur):

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

vous voulez dire 'Optional.ofNullable()' right? –

+1

@PatrickParker oui. J'ai devancé là-bas :-) Edité et réparé, merci de le remarquer! – Mureinik

+2

bel exemple. peut-être un bon nom pour cette fonction serait 'optionalMapOrElse', puisqu'il est un raccourci pour cette notation. –