2012-12-15 7 views
6

Wie funktioniert das? Ich kann keine Antwort finden.primitive-boolean Verkettung/Konvertierung von Zeichenketten

boolean bool=true; 
System.out.println("the value of bool is : " + true); 
//or 
System.out.println("the value of bool is : " + bool); 
  • Was sind die Dinge, die hinter der Szene los?
  • Wie wird der Boolean in den String geworfen, da ein Boolean nicht implizit Typ Casted sein kann?
  • Ist Autoboxing/Unboxing beteiligt?
  • Sind Methoden wie toString() oder String.valueOf() in irgendeiner Weise beteiligt?
+2

Lesen Sie diesen Artikel: http://www.znetdevelopment.com/blogs/2009/04/06/java-string-concatenation/ –

Antwort

13

Die genauen Regeln werden in der Java Language Specification buchstabiert, §5.1.11. String Conversion

diese Regeln nach, ist "str" + bool entspricht:

"str" + new Boolean(bool).toString() 

Das heißt, der Compiler einen großen Spielraum, wie genau erlaubt ist Der Gesamtausdruck wird ausgewertet. Von JLS §15.18.1. String Concatenation Operator +:

Eine Implementierung in einem Schritt Umwandlung und Verkettung durchführen zu vermeiden erstellen und dann Verwerfen ein Zwischen String-Objekt kann wählen. Um die Leistung der wiederholten Verkettung von Strings zu erhöhen, können ein Java-Compiler die StringBuffer Klasse oder eine ähnliche Technik verwendet werden, um die Anzahl von Zwischen String Objekten zu reduzieren, die durch Auswertung eines Ausdrucks erzeugt werden.

Für primitive Typen kann eine Implementierung auch die Schaffung eines Wrapper-Objekt optimieren entfernt in einen String direkt von einem primitiven Typ umwandeln.

Zum Beispiel mit meinem Compiler der folgenden:

boolean bool = true; 
System.out.println("the value of bool is : " + bool); 

genau entspricht:

boolean bool = true; 
System.out.println(new StringBuilder("the value of bool is : ").append(bool).toString()); 

Sie in identischen Bytecode führen:

Code: 
    0: iconst_1  
    1: istore_1  
    2: getstatic  #59     // Field java/lang/System.out:Ljava/io/PrintStream; 
    5: new   #166    // class java/lang/StringBuilder 
    8: dup   
    9: ldc   #168    // String the value of bool is : 
    11: invokespecial #170    // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 
    14: iload_1  
    15: invokevirtual #172    // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder; 
    18: invokevirtual #176    // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 
    21: invokevirtual #69     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
    24: return   
+1

macht die Tatsache, dass beide Codeschnipsel den gleichen Bytecode erzeugen, notwendigerweise, dass der erstere IS in den letzteren konvertiert wird?(vor der Umwandlung in den Bytecode, das ist) –

+0

@VinayWadhwa Ich glaube nicht, die JLS spezifiziert * wie * Sie sollten String-Verkettung implementieren - nur was das Ergebnis sein sollte. Soweit ich mich erinnern kann, hat der Snorcle Java-Compiler es jedoch mit einem 'StringBuffer' und einem' StringBuilder' implementiert. Es ist wahrscheinlich völlig zulässig, dass String-Verkettung eine intrinsische Operation in Ihrer JVM ist. – millimoose

+0

@ VinayWadhwa Dies scheint von [§15.18.1] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1) impliziert zu sein: Um die Leistung der wiederholten String-Verkettung zu erhöhen, kann ein Java-Compiler die StringBuffer-Klasse oder eine ähnliche Technik verwenden ... "und" Für primitive Typen kann eine Implementierung auch die Erstellung eines Wrapper-Objekts optimieren ... " – millimoose

2

Es ist ein Compiler Sache. Wenn der rechte Operand für Verkettungs ein Objekt ist, wird das Objekt die Methode toString() wohingegen, wenn der Operand ein primitiver gesendet dann der Compiler weiß, welche typspezifischen Verhalten zu verwenden, um die Primitive in eine Zeichenfolge konvertiert.

+0

ich sehe .. können Sie mich auf eine Dokumentation verweisen, die besagt, dass? –

+0

@ VinayWadhwa: siehe meine Antwort für eine Referenz. –

2

Der Compiler übersetzt es zu

StringBuilder sb = new StringBuilder("the value of bool is : "); 
sb.append(true); 
System.out.println(sb.toString()); 

Die Regeln der Verkettung und Umwandlung in the JLS erläutert.

+0

welcher Compiler? jeder Compiler? Wenn Sie mich auf die Quelle dieser Info hinweisen könnten, würde es sehr geschätzt werden. Die Referenz, die Sie angegeben haben, bezieht sich nicht auf Ihre Antwort, ich denke .. –

+0

Es heißt: * Eine Implementierung kann Konvertierung und Verkettung in einem Schritt ausführen, um zu vermeiden, ein intermediäres String-Objekt zu erstellen und dann zu verwerfen. Um die Leistung der wiederholten String-Verkettung zu erhöhen, kann ein Java-Compiler die StringBuffer-Klasse oder eine ähnliche Technik verwenden, um die Anzahl der String-Zwischenobjekte zu reduzieren, die durch Auswertung eines Ausdrucks erstellt werden. * Um die Regeln zu kennen, lesen Sie die JLS. Um zu wissen, wie es tatsächlich funktioniert, lesen Sie den Bytecode, der von Ihrem Compiler generiert wurde. –