wake-up-neo.com

Bei String.format ("% s", arg) werden Argumente mit Nullwert anders als "Null" angezeigt.

Betrachten Sie die benutzerdefinierte toString()-Implementierung eines Beans:

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

Dies ergibt this is null, wenn someField null ist.

Gibt es eine Möglichkeit, die standardmäßige null-Zeichenfolgendarstellung von Argumenten mit einem Nullwert in einem anderen Text zu überschreiben, d. H. ?, ohne explizit replaceAll(...) in der toString-Methode aufzurufen?

Note: Die Bean erbt von einer Superklasse, die Formattable ( http://docs.Oracle.com/javase/7/docs/api/Java/util/Formattable.html ) implementieren könnte, aber ich gerade Ich verstehe nicht, wie das funktioniert.

EDIT: Das Snippet ist aus Gründen des Beispiels zu stark vereinfacht, aber ich suche nicht nach ternären Operatorlösungen someField==null ? "?" : someField, weil:

  • toString() kann (möglicherweise) sehr viele Felder betreffen, daher ist die Überprüfung aller Felder zu umständlich und nicht fließend.
  • andere Leute, über die ich (wenn überhaupt) wenig Kontrolle habe, schreiben ihre eigenen Unterklassen.
  • wenn eine Methode aufgerufen wird und null zurückgibt, würde dies entweder bedeuten, dass die Methode zweimal aufgerufen oder eine lokale Variable deklariert wird.

Kann stattdessen etwas mit der Formattable-Schnittstelle oder mit einer benutzerdefinierten Formatter (was final btw. Ist) gemacht werden?

30
VH-NZZ

Mit Java 8 können Sie jetzt die optionale Klasse dafür verwenden:

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

Die schönste Lösung ist meiner Meinung nach die first-nonNull-Methode von Guava. Die folgende Methode stellt sicher, dass Sie eine leere Zeichenfolge drucken, wenn someField überhaupt einen Wert hat.

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

Guava-Dokumente .

Für eine Java 7-Lösung, die keine externen Bibliotheken erfordert:

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

Wenn Sie replaceAll() nicht verwenden möchten, können Sie einen Standardtext (String) für someField zuweisen. 

Wenn dies jedoch einmal der Fall ist, kann null erneut zugewiesen werden. Sie können also die Validierung für diesen Fall verwenden

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

Ein wenig zu spät zum Thema, aber dies könnte eine recht sauber aussehende Lösung sein: Erstellen Sie zunächst Ihre eigene Formatmethode ...

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

Dann benutze es wie du willst ...

@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);
}

Auf diese Weise sind mehrere, schwer lesbare, ternäre Operatoren nicht erforderlich.

5
JM Lord

Um zu vermeiden, dass der ternäre Operator wiederholt wird, können Sie ihn in eine besser lesbare Methode einbetten, die überprüft, ob Ihr Objekt null ist, und einen Standardwert zurückgeben, wenn es wahr ist

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

verwendungszweck

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, ""));

ausgabe:

field is  
id is -1 
id is  
3
Pshemo

Du könntest es einfach tun 

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

In Java 7 können Sie Objects.toString(Object o, String nullDefault) verwenden.

Auf Ihr Beispiel angewendet: String.format("this is %s", Objects.toString(this.someField, "?"));

1
Bob Rivers

Um den ursprünglichen Wert von someField beizubehalten (falls null ein gültiger Wert ist), können Sie einen ternären Operator verwenden.

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

verwenden Sie dann die Methode , ok

0
eebb88