2008-11-30 5 views
29

Ich benutzte den impliziten Aufruf von toString, wenn ich Debug-Informationen über ein Objekt haben wollte, weil im Falle, dass das Objekt null ist, keine Ausnahme ausgelöst wird.Expliziter vs impliziter Aufruf von toString

Zum Beispiel:

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

statt:

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

Gibt es einen Unterschied abgesehen von dem Null-Fall?
Kann letzterer Fall funktionieren, wenn ersterer nicht funktioniert?

Bearbeiten:
Was genau ist im Falle des impliziten Aufrufs getan?

Antwort

49

Es gibt wenig Unterschied. Verwenden Sie den, der kürzer ist und öfter arbeitet.

Wenn Sie tatsächlich den String-Wert eines Objekts aus anderen Gründen erhalten möchten, und wollen, dass es null, freundlich zu sein, dies tun:

String s = String.valueOf(obj); 

bearbeiten: Die Frage wurde erweitert, so dass ich lch erweitere meine Antwort.

In beiden Fällen kompilieren sie in etwa wie folgt:

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

Wenn Ihr toString() implizit ist, Sie, dass in der zweiten append sehen werden.

Wenn Sie sich den Quellcode zu Java anschauen, werden Sie sehen, dass StringBuilder.append(Object) wie folgt aussieht:

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

wo String.valueOf wie folgt aussieht:

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

Nun, wenn Sie toString() selbst umgehen Sie einen Null-Check und einen Stack-Frame und gehen direkt zu diesem in StringBuilder:

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

Also ... passiert in beiden Fällen sehr ähnliches. Man macht nur ein bisschen mehr Arbeit.

1

Kein Unterschied außer, wie Sie sagen, die Null-Sicherheit. Immer bevorzugen die ersteren zu den letzteren.

+0

warum ist es bevorzugt, die letztere Version zu benutzen? danke – Bartzilla

3

Wie andere gesagt haben - verwenden Sie die "" + obj Methode.

Laut The Java Language Spec:

  • Wenn der Ausdruck null ist, verwenden "null"
  • Primitive Typen umgewandelt werden unter Verwendung der geschachtelten-Typkonstruktor new Boolean(X) oder was auch immer
  • toString() aufgerufen wird (oder gleichwertig)
  • Wenn das Ergebnis von toString()null ist, verwenden Sie "null"
  • Verketten Sie die Strings.
+0

Der 4. Punkt auf deiner Liste hat mein Interesse geweckt. Für Objekte, die keine Zeichenfolgen sind, hängt String.valueOf (String.valueOf (ob)) an. Es ist billig und erfüllt die Anforderungen, nehme ich an. – Dustin

+0

heh - raffiniert. Wenn ich ehrlich bin, wusste ich es nicht, bis ich mir die Spezifikation ansah - die Unterscheidung war nie wichtig. Ein gutes Beispiel dafür, warum ich immer zur Hauptquelle gehe, wenn ich kann. – Draemon

1

Eigentlich, wenn Ihre Invariante sagt, das Objekt sollte nie null sein, ist es egal. Es hängt also davon ab, ob Sie obj als null akzeptieren oder nicht.

0

Es ist ganz einfach eine allgemeine Referenztyp zu schreiben.

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

Laufen sie die erforderliche Leistung gibt:

javac ref.java && java ref 
foo 
+0

Ich sehe nicht, wo das die Frage beantwortet ... – geisterfurz007

Verwandte Themen