字符串连接需要多少个内存位置?
String myStringVariable = "Hello";
以下两个陈述:
String s = "ABC" + "Hello" + "DEF";
和
String s = "ABC";
s = s + "Hello";
s = s + "DEF";
和
String s = "ABC" + myStringVariable + "DEF";
哪个会消耗更多内存?在哪种情况下StringBuilder最有用?
答案 0 :(得分:3)
StringBuilder
在任何情况下都是有用的,如编写的那样 - 编译器将尽可能重用相同的StringBuilder
实例。当你在循环中添加字符串时,它略微有用。 (我说“略微”,因为大部分时间你并没有真正添加 许多字符串,也不是那个很长。差异会显示在微基准测试中但是你的程序不是一个,除非你正在编写一个模板引擎或类似的东西。)
创建垃圾StringBuilder
并不会像GC压力那样“浪费内存”。事实上,像Java这样的世代清道夫GC被设计用于创建大量非常短暂的垃圾对象。我不担心,除非你真的在GC上花了太多时间。
将String
内容重复复制到StringBuilder
s也是浪费,但再一次,不太可能在循环之外产生重大影响。
答案 1 :(得分:3)
第一个语句将由编译器转换为String s = "ABCDEF";
,因此不会有连接
第二个语句将由编译器转换为此代码(或类似的东西)
String s = "ABC";
StringBuilder sb = new StringBuilder(s);
sb.append("DEF");
s = sb.toString();
答案 2 :(得分:2)
String s = "ABC" + "DEF";
在编译时解决,并且StringBuilder
过去没有连接。
和
String s = "ABC";
s = s + "DEF";
在这种情况下,StringBuilder(string...).toString()
可以在运行时解析String
。
所以你需要使用StringBuilder
,在你的情况下,它的性能差异可以忽略不计。
不要使用多少串联“+”,在较少量的连接中不会造成太大的伤害。如果你正在处理更大的数量,则更喜欢使用StringBuilder和append方法。
如果您将字符串在大范围内与+
连接,则可以看到区别,然后转到StringBuilder
追加。
答案 3 :(得分:2)
我创建了课程Main
:
public class Main {
public String foo() {
String s = "ABC" + "DEF";
return s;
}
public String foo1() {
String s = "ABC";
s = s + "DEF";
return s;
}
}
并反编译:
public java.lang.String foo();
Signature: ()Ljava/lang/String;
Code:
0: ldc #2 // String ABCDEF
2: astore_1
3: aload_1
4: areturn
public java.lang.String foo1();
Signature: ()Ljava/lang/String;
Code:
0: ldc #3 // String ABC
2: astore_1
3: new #4 // class java/lang/StringBuilder
6: dup
7: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
10: aload_1
11: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: ldc #7 // String DEF
16: invokevirtual #6 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #8 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore_1
23: aload_1
24: areturn
方法foo
使串联字符串编译时,但方法foo1
在运行时连接字符串并使用StringBuilder
。
首先示例使用更少的内存。
我使用Oracle JDK 1.7_45和默认属性。
答案 4 :(得分:1)
哪个会占用更多内存?
java规范15.8.1 String Concatenation Operator +:
除非表达式是a,否则新创建String对象(第12.5节) 编译时常量表达式(§15.28)。
实现可以选择执行转换和连接 在一步中避免创建然后丢弃中间体 字符串对象。增加重复字符串的性能 连接,Java编译器可以使用StringBuffer类或a 类似的技术减少了中间String对象的数量 通过评估表达式创建的。
第一句话,
String s = "ABC" + "Hello" + "DEF";
此表达式是编译时常量表达式。将一步完成。在运行时没有创建对象。
第二声明:
String s = "ABC";
s = s + "Hello";
s = s + "DEF";
此语句将创建一个包含"ABCHELLO"
的新字符串。第三个语句将创建一个包含"ABCHELLODEF"
的新字符串。此字符串连接将使用StringBuilder
。
第三条陈述
String s = "ABC" + myStringVariable + "DEF";
与第一个语句不同,此语句将在运行时创建一个新实例,因为它不是编译时常量表达式。
但是使用StringBuilder
来连接这样的三个字符串不会导致性能提升,除非你正在使用计数很重要的字符串数。
答案 5 :(得分:0)
当您想要使用字符串时,StringBuilder非常有用。通过组合字符串动态创建字符串它只会占据一个物体。
如果每次连接都使用字符串,则会在内存中创建新对象。