web-dev-qa-db-fra.com

Faire que String.format ("% s", arg) affiche les arguments avec la valeur null différemment de "null"

Considérez l'implémentation personnalisée toString() d'un bean:

@Override
public String toString() {
    String.format("this is %s", this.someField);
}

Cela donne this is null si someField est null.

Existe-t-il un moyen de remplacer la représentation par défaut de la chaîne null des arguments à valeur NULL par un autre texte, c'est-à-dire ?sans appeler explicitement replaceAll(...) dans la méthode toString?

Note: le bean hérite d'une super-classe pouvant implémenter Formattable ( http://docs.Oracle.com/javase/7/docs/api/Java/util/Formattable.html ) mais je viens ne semble pas comprendre comment faire ce travail.

EDIT: l'extrait de code est trop simplifié à titre d'exemple, mais je ne cherche pas de solution opérateur ternaire someField==null ? "?" : someField car:

  • il peut y avoir (potentiellement) un grand nombre de champs impliqués dans toString(), aussi la vérification de tous les champs est trop lourde et peu fluide.
  • d'autres personnes sur lesquelles j'ai peu de contrôle (le cas échéant) écrivent leurs propres sous-classes.
  • si une méthode est appelée et renvoie la valeur null, cela impliquerait soit d'appeler la méthode deux fois, soit de déclarer une variable locale.

Peut-on plutôt faire quelque chose en utilisant l'interface Formattable ou en utilisant une certaine Formatter personnalisée (qui est final btw.)?

30
VH-NZZ

Avec Java 8, vous pouvez maintenant utiliser la classe facultative pour cela:

import static Java.util.Optional.ofNullable;
...
String myString = null;
System.out.printf("myString: %s",
    ofNullable(myString).orElse("Not found")
);
31
Dmitry Klochkov

La meilleure solution, à mon avis, utilise la méthode Objects de Guava, firstNonNull. La méthode suivante garantira que vous imprimerez une chaîne vide si someField est jamais nul.

String.format("this is %s", MoreObjects.firstNonNull(this.someField, ""));

Documents sur la goyave .

Pour une solution Java 7 ne nécessitant pas de bibliothèques externes:

String.format("this is %s", Objects.toString(this.someField, "?"));
16
Klitos Kyriacou

Si vous ne souhaitez pas utiliser replaceAll(), vous pouvez attribuer un texte par défaut (String) à someField

Mais si le temps le permet, null peut être attribué à nouveau. Donc, vous pouvez utiliser la validation pour ce cas

 this.someField == null ? "defaultText" : this.someField

Un peu tard sur le sujet, mais cela pourrait être une solution plutôt propre: Commencez par créer votre propre méthode de formatage ...

private static String NULL_STRING = "?";

private static String formatNull(String str, Object... args){
    for(int i = 0; i < args.length; i++){
        if(args[i] == null){
            args[i] = NULL_STRING;
        }
    }

    return String.format(str, args);
}

Ensuite, utilisez-le comme vous voulez ...

@Test
public void TestNullFormat(){
    Object ob1 = null;
    Object ob2 = "a test";

    String str = formatNull("this is %s", ob1);
    assertEquals("this is ?", str);

    str = formatNull("this is %s", ob2);
    assertEquals("this is a test", str);
}

Ceci élimine le besoin d'opérateurs ternaires multiples, difficiles à lire.

5
JM Lord

Pour éviter de répéter l'opérateur ternaire, vous pouvez l'envelopper dans une méthode plus lisible qui vérifiera si votre objet est null et retournera une valeur par défaut si elle est vraie

static <T> T changeNull(T arg, T defaultValue) {
    return arg == null ? defaultValue : arg;
}

usage

String field = null;
Integer id = null;
System.out.printf("field is %s %n", changeNull(field, ""));
System.out.printf("id is %d %n", changeNull(id, -1));
System.out.printf("id is %s %n", changeNull(field, ""));

sortie:

field is  
id is -1 
id is  
3
Pshemo

Tu pourrais juste faire 

String.format("this is %s", (this.someField==null?"DEFAULT":this.someField));
2
joey.enfield

À partir de Java 7, vous pouvez utiliser Objects.toString(Object o, String nullDefault).

Appliqué à votre exemple: String.format("this is %s", Objects.toString(this.someField, "?"));

1
Bob Rivers

Pour conserver la valeur d'origine someField (dans le cas où null est une valeur valide), vous pouvez utiliser un opérateur ternary .

String.format("This is %s", (this.someField == null ? "unknown" : this.someField));
1
Chris Forrence
public static String format(String format, Object... args){
    for (int i=0;i<args.length;i++){
        if (args[i]==null) args[i]="";
    }
    return String.format(format,args);
}

puis utilisez la méthode , ok

0
eebb88