2012-12-15 40 views
6

这是如何工作的?我似乎无法找到答案。primitive-boolean要字符串连接/转换

boolean bool=true; 
System.out.println("the value of bool is : " + true); 
//or 
System.out.println("the value of bool is : " + bool); 
  • 有哪些东西会在幕后?
  • 布尔值如何被转换为字符串作为布尔值不能隐含 类型转换?
  • 自动装箱/拆箱是否涉及?
  • toString()String.valueOf()这样的方法是以某种方式参与吗?
+2

阅读本文:http://www.znetdevelopment.com/blogs/2009/04/06/java-string-concatenation/ –

回答

13

确切的规则是在Java语言规范拼写,§5.1.11. String Conversion

根据这些规则,"str" + bool相当于:

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

这就是说,允许编译器相当大的余地究竟怎么了评估整体表达。来自JLS §15.18.1. String Concatenation Operator +

一个实现可能选择在一个步骤中执行转换和连接以避免创建并丢弃中间String对象。为了提高重复字符串连接的性能,Java编译器可以使用类或类似技术来减少通过评估表达式创建的中间对象的数量。

对于基元类型,实现还可以通过直接从基元类型转换为字符串来优化封装器对象的创建。

例如,我的编译如下:

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

完全等同于:

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

他们导致相同的字节码:

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

是否确实代码片断创建相同的字节码必然意味着前者被转换为后者?(在转换为字节码之前,就是这样) –

+0

@VinayWadhwa我不认为JLS指定了*你应该如何实现字符串连接 - 仅仅是结果应该是什么。然而,就我所知,Snorcle Java编译器已经使用'StringBuffer',然后是一个'StringBuilder'来实现它。将字符串连接作为JVM中的内部操作可能是完全允许的。 – millimoose

+0

@VinayWadhwa这似乎暗示了[§15.18.1](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.1):“为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似的技术......“和”对于原始类型,实现也可以优化掉包装对象的创建......“ – millimoose

2

这是一个编译器的东西。如果连接的右操作数是一个对象,则发送该对象的方法,而如果该操作数是基元,则编译器知道使用哪种类型特定的行为将该基元转换为字符串。

+0

我看到..你能指点我的文档说明吗? –

+0

@VinayWadhwa:查看我的答案以供参考。 –

2

编译器编译它到

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

连接和转换的规则在the JLS中解释。

+0

哪个编译器?每个编译器? 如果你能指点我的信息的来源,它将不胜感激。 您提供的参考文献与您的答案无关,我认为...... –

+0

它表示:*实现可以选择在一个步骤中执行转换和连接,以避免创建并丢弃中间String对象。为了提高重复字符串连接的性能,Java编译器可以使用StringBuffer类或类似的技术来减少通过评估表达式创建的中间String对象的数量*要了解规则,请阅读JLS。要知道它是如何工作的,请阅读由编译器生成的字节码。 –