Java concat拼接操作中的字符串是否会创建在字符串常量池?
Java字符串拼接场景下字符串常量池创建规则
问题对应的参考代码如下:
String a = args[0]; // 接收运行时的用户键盘输入 String b = a + "foo1"; String c = "foo2" + "foo3";
针对代码中"foo1"、"foo2"、"foo3"三个字面量是否进入字符串常量池,核心判断逻辑是:只有编译期被确定为需要保留的字符串字面量,才会在类加载阶段被创建并存入字符串常量池,和后续拼接逻辑没有直接绑定关系,具体结论如下:
"foo1"会被创建在字符串常量池中
它是代码中显式声明的字符串字面量,属于编译期可确定的常量。虽然a是运行时才能拿到具体值的用户输入,a + "foo1"的拼接动作会在运行时通过StringBuilder完成,最终生成的b是堆中的普通字符串对象、不会自动入池,但这不会影响"foo1"本身作为独立字面量,在类加载阶段被存入字符串常量池。"foo2"、"foo3"默认不会单独在字符串常量池中创建
这两个字面量只出现在双常量拼接的表达式中,Java编译器会在编译阶段直接做常量折叠优化:两个编译期可确定的字面量拼接,会被直接计算为最终结果"foo2foo3",编译后的Class文件常量池里只会保留"foo2foo3"这一个条目,不会单独存储"foo2"、"foo3",自然也不会在运行时的字符串常量池中单独创建这两个字符串对象。如果代码其他位置存在单独引用"foo2"或"foo3"的逻辑,编译器才会将这两个字面量保留在Class常量池中,后续类加载时对应字符串才会进入运行时常量池。
补充说明:所有包含运行时变量的字符串拼接(比如示例中
a + "foo1"),最终生成的新字符串都是堆上的普通对象,不会自动进入字符串常量池,除非手动调用String.intern()方法主动将其加入常量池。
内容的提问来源于stack exchange,提问作者Hung Minh Tran
相关产品推荐
相关产品推荐

