2008-11-30 14 views
29

Solía ​​utilizar la llamada implícita de toString cuando quería información de depuración sobre un objeto, porque en el caso de que el objeto sea nulo, no arroja una excepción.Llamada explícita vs implícita de toString

Por ejemplo:

System.out.println("obj: "+obj); 

en lugar de:

System.out.println("obj: "+obj.toString()); 

¿Hay alguna diferencia aparte del caso nulo?
¿Puede funcionar este último caso, cuando el primero no?

Edit:
¿Qué se hace exactamente, en el caso de la llamada implícita?

Respuesta

49

Hay poca diferencia. Usa el que es más corto y funciona más a menudo.

Si realmente desea obtener el valor de cadena de un objeto por otras razones, y quiere que sea nula amable, hacer esto:

String s = String.valueOf(obj); 

Editar: La pregunta se extiende, por lo que' extenderé mi respuesta

En ambos casos, se compilan a algo como lo siguiente:

System.out.println(new StringBuilder().append("obj: ").append(obj).toString()); 

Cuando su toString() es implícita, verá que en la segunda anexión.

Si nos fijamos en el código fuente de Java, verá que StringBuilder.append(Object) se parece a esto:

public StringBuilder append(Object obj) { 
    return append(String.valueOf(obj)); 
} 

donde String.valueOf se parece a esto:

public static String valueOf(Object obj) { 
    return (obj == null) ? "null" : obj.toString(); 
} 

Ahora, si usted mismo toString() , omite una verificación nula y un marco de pila e ir directamente a esto en StringBuilder:

public StringBuilder append(String str) { 
    super.append(str); 
    return this; 
} 

Entonces ... cosas muy similares ocurren en ambos casos. Uno solo hace un poco más de trabajo.

1

Ninguna diferencia excepto, como dices, la seguridad nula. Siempre prefiero lo primero a lo último.

+0

¿Por qué es preferible usar la última versión? gracias – Bartzilla

3

Como han dicho otros - use el método "" + obj.

Según The Java Language Spec:

  • Si el término es nulo, utilice "null"
  • tipos primitivos se convierten usando el tipo caja constructor new Boolean(X) o lo que sea se invoca
  • toString() (o equivalente)
  • si el resultado de toString() es null, utilice "null"
  • Concatenar las cadenas.
+0

El 4º artículo en su lista despertó mi interés. Para las cosas que no son cadenas, se agrega String.valueOf (String.valueOf (ob)). Es barato y cumple con los requisitos, supongo. – Dustin

+0

heh - ingenioso. Si soy sincero, no lo sabía hasta que miré la especificación tampoco; la distinción nunca ha importado. Un buen ejemplo de por qué siempre voy a la fuente primaria si puedo. – Draemon

1

En realidad, si su invariante dice que el objeto nunca debe ser nulo, no importa. Entonces depende de si acepta o no que obj sea nulo.

0

Es bastante fácil escribir un tipo de referencia genérico.

class ref 
{ 
    static public class Reference<T> 
    { 
    private T value; 
    public Reference(T value) { set(value); } 
    public Reference() { set(null); } 
    public void set (T value) { this.value = value; } 
    public T get() { return this.value; } 
    public String toString() { return String.valueOf(this.value); } 
    } 

    static void fillString (Reference<String> str) 
    { 
    str.set("foo"); 
    } 

    public static void main (String[] args) 
    { 
    Reference<String> str = new Reference<String>(""); 
    fillString(str); 
    System.out.println (str); 
    } 
} 

Correr da la salida requerida:

javac ref.java && java ref 
foo 
+0

No puedo ver dónde responde esto la pregunta ... – geisterfurz007

Cuestiones relacionadas