使用此代码模拟您上面的问题:
String s = "asd";
s+=42;
System.out.println(s);
会产生这个byteCote:
Code:
0: ldc #16 // String asd
2: astore_1
3: new #18 // class java/lang/StringBuilder
6: dup
7: aload_1
8: invokestatic #20 // Method java/lang/String.valueOf:(
java/lang/Object;)Ljava/lang/String;
11: invokespecial #26 // Method java/lang/StringBuilder."<
nit>":(Ljava/lang/String;)V
14: bipush 42
16: invokevirtual #29 // Method java/lang/StringBuilder.ap
end:(I)Ljava/lang/StringBuilder;
19: invokevirtual #33 // Method java/lang/StringBuilder.to
tring:()Ljava/lang/String;
22: astore_1
23: getstatic #37 // Field java/lang/System.out:Ljava/
o/PrintStream;
26: aload_1
27: invokevirtual #43 // Method java/io/PrintStream.printl
:(Ljava/lang/String;)V
30: return
查看数字 16 和 19,您可以清楚地看到它调用 StringBuilder 类并在内部调用 append method 到附加 42 的 += operator 和 line 19 然后将其转换为字符串。
编辑:
上面的代码实际上是这样写的:s = s + 42,所以每次你使用加号操作符到一个 Integer 到 String 时,它都会调用它的包装类并调用 toString 方法
JLS
Any type may be converted to type String by string conversion.
A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression (§15.9):
If T is boolean, then use new Boolean(x).
If T is char, then use new Character(x).
If T is byte, short, or int, then use new Integer(x).
If T is long, then use new Long(x).
If T is float, then use new Float(x).
If T is double, then use new Double(x).
This reference value is then converted to type String by string conversion.
Now only reference values need to be considered:
If the reference is null, it is converted to the string "null" (four ASCII characters n, u, l, l).
Otherwise, the conversion is performed as if by an invocation of the toString method of the referenced object with no arguments; but if the result of invoking the toString method is null, then the string "null" is used instead.