让我们看一下Java中的以下简单表达式
int x=15;
String temp="x = "+x;
编译器在内部将"x = "+x; 转换为StringBuilder,并使用.append(int) 将整数“添加”到字符串中。
5.1.11. String Conversion
任何类型都可以通过字符串转换转换为String类型。
原始类型 T 的值 x 首先被转换为参考值
好像通过将其作为参数提供给适当的类实例
创建表达式(§15.9):
- 如果 T 是布尔值,则使用 new Boolean(x)。
- 如果 T 是 char,则使用 new Character(x)。
- 如果 T 是 byte、short 或 int,则使用 new Integer(x)。
- 如果 T 很长,则使用 new Long(x)。
- 如果 T 是浮点数,则使用 new Float(x)。
- 如果 T 为 double,则使用 new Double(x)。
然后这个引用值被字符串转换成String类型
转换。
现在只需要考虑参考值:
- 如果引用为 null,则将其转换为字符串“null”(四个 ASCII 字符 n、u、l、l)。
- 否则,转换就像通过调用不带参数的引用对象的 toString 方法一样执行;但
如果调用 toString 方法的结果为 null,则
改为使用字符串“null”。
toString方法由原始类Object定义
(§4.3.2)。许多类覆盖它,特别是 Boolean、Character、
整数、长整数、浮点数、双精度和字符串。
有关字符串转换上下文的详细信息,请参阅第 5.4 节。
15.18.1.
字符串拼接的优化:
实现可以选择执行转换和连接
一步避免创建然后丢弃中间体
字符串对象。提高重复字符串的性能
连接,Java 编译器可以使用 StringBuffer 类或
减少中间字符串对象数量的类似技术
通过评估表达式创建的。
对于原始类型,实现也可以优化掉
通过直接从原语转换来创建包装器对象
输入一个字符串。
优化后的版本实际上不会先进行完整的字符串转换。
这是编译器使用的优化版本的一个很好的说明,尽管没有转换原语,您可以在其中看到编译器在后台将内容更改为 StringBuilder:
http://caprazzi.net/posts/java-bytecode-string-concatenation-and-stringbuilder/
这个java代码:
public static void main(String[] args) {
String cip = "cip";
String ciop = "ciop";
String plus = cip + ciop;
String build = new StringBuilder(cip).append(ciop).toString();
}
生成这个 - 看看这两种连接样式如何导致相同的字节码:
L0
LINENUMBER 23 L0
LDC "cip"
ASTORE 1
L1
LINENUMBER 24 L1
LDC "ciop"
ASTORE 2
// cip + ciop
L2
LINENUMBER 25 L2
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESTATIC java/lang/String.valueOf(Ljava/lang/Object;)Ljava/lang/String;
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 3
// new StringBuilder(cip).append(ciop).toString()
L3
LINENUMBER 26 L3
NEW java/lang/StringBuilder
DUP
ALOAD 1
INVOKESPECIAL java/lang/StringBuilder.<init>(Ljava/lang/String;)V
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
ASTORE 4
L4
LINENUMBER 27 L4
RETURN
看上面的例子,看看上面给出的例子中的源代码是如何生成字节码的,你会注意到编译器内部已经对下面的语句进行了转换
cip+ciop;
进入
new StringBuilder(cip).append(ciop).toString();
换句话说,字符串连接中的运算符+ 实际上是更冗长的StringBuilder 成语的简写。