Explícita vs chamada implícita de toString
Pergunta
Eu costumava usar a chamada implícita de toString quando querem algumas informações de depuração sobre um objeto, porque em caso do objeto é nulo não lançar uma exceção.
Por exemplo:
System.out.println("obj: "+obj);
em vez de:
System.out.println("obj: "+obj.toString());
Existe alguma diferença para além do caso nulo?
Pode o último trabalho caso, quando o primeiro não?
Edit:
O que exatamente é feito, no caso da chamada implícita?
Solução
Há pouca diferença. Use o que é mais curto e trabalha com mais freqüência.
Se você realmente deseja obter o valor da seqüência de um objeto por outras razões, e quer que ele seja nula amigável, faça o seguinte:
String s = String.valueOf(obj);
Editar :. A questão foi estendido, então eu vou estender a minha resposta ??p>
Em ambos os casos, eles compilar para algo como o seguinte:
System.out.println(new StringBuilder().append("obj: ").append(obj).toString());
Quando seu toString()
está implícito, você vai ver que na segunda acréscimo.
Se você olhar para o código-fonte java, você verá que parece StringBuilder.append(Object)
como este:
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
onde String.valueOf
esta aparência:
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Agora, se você toString()
mesmo, você ignorar um cheque nulo e um quadro de pilha e ir direto para isso em StringBuilder
:
public StringBuilder append(String str) {
super.append(str);
return this;
}
Então ... coisas muito semelhante acontece em ambos os casos. Um só faz um pouco mais de trabalho.
Outras dicas
Como já foi dito -. Usar o método "" + obj
De acordo com o linguagem Java Spec :
- Se o termo é nulo, o uso
"null"
- tipos primitivos são convertidos usando o
new Boolean(X)
construtor do tipo box ou qualquer -
toString()
é invocado (ou equivalente) - Se o Resultado de
toString()
énull
, uso"null"
- concatenar os strings.
Nenhuma diferença, exceto, como você diz, a segurança nulo. Prefira sempre a primeira para a segunda.
Na verdade, se o seu invariável diz o objeto nunca deve ser nula, não importa. Então, isso depende se ou não você aceitar obj ser nulo.
É muito fácil escrever um tipo de referência genérica.
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);
}
}
Running dá a saída necessária:
javac ref.java && java ref
foo