5

当您将字符串与 int 等基元连接时,它是否首先自动装箱该值。

前任。

String string = "Four" + 4;

它如何将值转换为Java中的字符串?

4

3 回答 3

5

要查看 Java 编译器生成的内容,使用它javap -c来显示生成的实际字节码总是很有用的:

例如下面的 Java 代码:

String s1 = "Four" + 4;
int i = 4;
String s2 = "Four" + i;

将产生以下字节码:

   0:   ldc     #2; //String Four4
   2:   astore_1
   3:   iconst_4
   4:   istore_2
   5:   new     #3; //class java/lang/StringBuilder
   8:   dup
   9:   invokespecial   #4; //Method java/lang/StringBuilder."<init>":()V
   12:  ldc     #5; //String Four
   14:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/
String;)Ljava/lang/StringBuilder;
   17:  iload_2
   18:  invokevirtual   #7; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
   21:  invokevirtual   #8; //Method java/lang/StringBuilder.toString:()Ljava/la
ng/String;
   24:  astore_3
   25:  return

由此我们可以看出:

  • 在 的情况下"Four" + 4,Java 编译器(我使用的是 JDK 6)足够聪明地推断出这是一个常量,因此在运行时没有计算工作量,因为字符串在编译时连接
  • In the case of "Four" + i, the equivalent code is new StringBuilder().append("Four").append(i).toString()
  • Autoboxing is not involved here as there is an StringBuilder.append(int) method which according to the docs is using String.valueOf(int) to create the string representation of the integer.
于 2012-09-16T07:39:46.940 回答
4

java 编译器实际上创建一个1并调用该方法。从字节码中可以看出:StringBuilderappend()

22  invokespecial java.lang.StringBuilder(java.lang.String) [40]
...   
29  invokevirtual java.lang.StringBuilder.append(int) : java.lang.StringBuilder [47]
32  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [51]

尽管如此,该行为与装箱然后调用toString(): "Four" + new Integer(4).toString()- 我相信语言设计者的想法相同。


(1) 确切地说,编译器已经将字符串文字和 int 文字连接到单个字符串文字"Four4"。您可以在字节码中以下行的字节码中看到它:

 0  ldc <String "Four4"> [19]
于 2012-09-16T07:24:33.633 回答
0

根据http://jcp.org/aboutJava/communityprocess/jsr/tiger/autoboxing.html,只要需要引用类型(例如本例中的 Integer 类),就会对原始类型进行自动装箱

因此 int 将被转换为 Integer,然后调用该整数对象 toString() 方法,并将其结果附加到前面的字符串中。

于 2012-09-16T07:34:51.730 回答