内存中创建了多少个字符串?
说我有这个String
表达式
String hi = "Tom" + "Brady" + "Goat"
我知道字符串池“允许运行时通过在池中保留不可变字符串来节省内存” 字符串池
字符串池中将创建多少个字符串?
我最初的猜测是5 – "Tom"
, "Brady"
, "Goat"
, "TomBrady"
, "TomBradyGoat"
,因为String
连接的操作顺序(从左到右?)或者它只是最终结果,“ TomBradyGoat“,它存储在字符串池中?
在运行时,该段代码将转换为单个String
对象。 编译器将在编译时处理串联,并在常量池中添加单个值。
你在这里得到的是一个常量表达式 ,如JLS第15.28节所定义。
常量表达式是表示基本类型的值的表达式或不突然完成的字符串,仅使用以下内容组成:
原始类型的文字和String类型的文字(§3.10.1,§3.10.2,§3.10.3,§3.10.4,§3.10.5)
转换为基本类型并转换为String类型(第15.16节)
一元运算符+, – ,〜,和! (但不是++或 – )(§15.15.3,§15.15.4,§15.15.5,§15.15.6)
乘法运算符*,/和%(§15.17)
加法运算符+和 – (§15.18)
(其他可能性)
编译器确定表达式"Tom" + "Brady" + "Goat"
是一个常量表达式,因此它将表达式本身评估为"TomBradyGoat"
。
JVM在字符串池中只有一个字符串, "TomBradyGoat"
。
其他答案解释了为什么只有1个String被添加到String池中。 但是,如果您想自己检查并进行一些测试,可以查看字节码以查看创建并添加到字符串池的String数。 例如:
EX1:
public static void main(String[] args) { String hi = "Tom" + "Brady" + "Goat"; }
字节代码:
// access flags 0x9 public static main(String[]) : void L0 LINENUMBER 6 L0 LDC "TomBradyGoat" ASTORE 1 L1 LINENUMBER 7 L1 RETURN L2 LOCALVARIABLE args String[] L0 L2 0 LOCALVARIABLE hi String L1 L2 1 MAXSTACK = 1 MAXLOCALS = 2
如您所见,只创建了1个String
EX2:
public static void main(String[] args) { String str1 = "Tom"; String str2 = "Brady"; String str3 = "Goat"; String str = str1 + str2 + str3; }
字节码:
// access flags 0x9 public static main(String[]) : void L0 LINENUMBER 6 L0 LDC "Tom" ASTORE 1 L1 LINENUMBER 7 L1 LDC "Brady" ASTORE 2 L2 LINENUMBER 8 L2 LDC "Goat" ASTORE 3 L3 LINENUMBER 9 L3 NEW StringBuilder DUP ALOAD 1: str1 INVOKESTATIC String.valueOf (Object) : String INVOKESPECIAL StringBuilder. (String) : void ALOAD 2: str2 INVOKEVIRTUAL StringBuilder.append (String) : StringBuilder ALOAD 3: str3 INVOKEVIRTUAL StringBuilder.append (String) : StringBuilder INVOKEVIRTUAL StringBuilder.toString () : String ASTORE 4 L4 LINENUMBER 10 L4 RETURN L5 LOCALVARIABLE args String[] L0 L5 0 LOCALVARIABLE str1 String L1 L5 1 LOCALVARIABLE str2 String L2 L5 2 LOCALVARIABLE str3 String L3 L5 3 LOCALVARIABLE str String L4 L5 4 MAXSTACK = 3 MAXLOCALS = 5
如您所见,创建了4个字符串
正如其他人所提到的,编译器足以优化这个非常简单的示例,但是如果你有更复杂的function(这可能是你关心的),它可能不会。 例如:
String a = "Tom"; String b = "Brady"; String c = a; c += b;
这将导致创建3个字符串。