primitive-boolean To String concatenation / conversion
这是如何运作的? 我似乎无法找到答案。
boolean bool=true; System.out.println("the value of bool is : " + true); //or System.out.println("the value of bool is : " + bool);
- 幕后发生的事情是什么?
- 如何将布尔值转换为String,因为布尔值不能隐式类型转换?
- 是否涉及Autoboxing / Unboxing ?
- 是否以某种方式涉及
toString()
或String.valueOf()
等方法?
精确的规则在Java语言规范§5.1.11中有详细说明。 字符串转换
根据这些规则, "str" + bool
相当于:
"str" + new Boolean(bool).toString()
也就是说,编译器在如何评估整体表达式方面具有相当大的余地。 来自JLS§15.18.1。 字符串连接运算符+ :
实现可以选择在一个步骤中执行转换和连接,以避免创建然后丢弃中间String对象。 为了提高重复字符串连接的性能,Java编译器可以使用
StringBuffer
类或类似技术来减少通过表达式求值创建的中间String
对象的数量。对于基本类型,实现还可以通过直接从基元类型转换为字符串来优化包装器对象的创建。
例如,我的编译器如下:
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."":(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
这是编译器的事情。 如果连接的右操作数是对象,则向对象发送toString()
方法,而如果操作数是基元,则编译器知道使用哪种特定于类型的行为将基元转换为字符串。
编译器将其转换为
StringBuilder sb = new StringBuilder("the value of bool is : "); sb.append(true); System.out.println(sb.toString());
JLS中解释了连接和转换的规则。