java string null string-formatting string.format

java - Make String.format("% s", arg) muestra los argumentos de valor nulo de manera diferente a "null"



string-formatting (10)

Considere la implementación toString() de un bean:

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

Esto da como resultado que this is null si someField es nulo.

¿Hay alguna forma de anular la representación de cadena null predeterminada de los argumentos de valor nulo en otro texto, es decir ? sin llamar explícitamente replaceAll(...) en el método toString ?

Nota : el bean se hereda de una superclase que podría implementar Formattable ( http://docs.oracle.com/javase/7/docs/api/java/util/Formattable.html ) pero parece que no entiendo cómo hacer que esto funcione

EDITAR : El fragmento de código está simplificado en exceso por ejemplo, pero no estoy buscando soluciones de operador ternario someField==null ? "?" : someField someField==null ? "?" : someField someField==null ? "?" : someField porque:

  • puede haber (potencialmente) muchos campos involucrados en toString() por lo que verificar todos los campos es demasiado engorroso y no es fluido.
  • otras personas sobre las que tengo poco control (si las hay) están escribiendo sus propias subclases.
  • si se llama a un método y se devuelve un valor nulo, esto implicaría llamar al método dos veces o declarar una variable local.

Más bien, ¿se puede hacer algo utilizando la interfaz Formattable o teniendo un Formatter personalizado (que es el final cierto)?


Con java 8 ahora puedes usar la clase opcional para esto:

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


Desde Java 7, puede usar Objects.toString(Object o, String nullDefault) .

Aplicado a su ejemplo: String.format("this is %s", Objects.toString(this.someField, "?"));


La mejor solución, en mi opinión, es usar el método de Objetos de Guava, firstNonNull. El siguiente método asegurará que imprimirá una cadena vacía si alguna parte del campo es nula.

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

Documentos de guayaba .


Para evitar repetir el operador ternario, puede envolverlo en un método más legible que verificará si su objeto es null y devolverá algún valor predeterminado si es verdadero como

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

uso

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

salida:

field is id is -1 id is


Para mantener el valor original de someField (en caso de que null sea un valor válido), puede utilizar un operador ternario .

String.format("This is %s", (this.someField == null ? "unknown" : this.someField));


Para una solución Java 7 que no requiere bibliotecas externas:

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


Si no desea utilizar replaceAll() , puede asignar un texto predeterminado (Cadena) para someField .

Pero si algún tiempo esto puede asignar null nuevo. Así que puedes usar la validación para ese caso.

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


Un poco tarde en el tema, pero esto podría ser una solución bastante limpia: primero, cree su propio método de formato ...

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

Entonces, úsalo como lo harás ...

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

Esto elimina la necesidad de múltiples operadores ternarios difíciles de leer.


Usted podría simplemente hacer

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


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

entonces usa el método, ok