[java] "Hello"和new String("Hello")产生String对象的区别

本文通过对比不同方式创建字符串的字节码,揭示了Java中字符串创建的两种常见方式在内存中的表现形式。详细解释了使用new String()与直接赋值方式创建字符串的区别,并通过实例说明了这两种方式如何影响字符串的内存分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题在于看了<practical java>的实践 31:如欲进行字符串接合,StringBuffer优于String.

其中使用new String("...")形式产生的bytecode中显示产生了两个String对象!

做了以下实验:比较Test.java和Test1.java两者之间的bytecode.

package com.my;

public class Test {
 public static void main(String[] args) {
  String str = new String("hello");
 }
}

 


 

package com.my;

public class Test2 {
 public static void main(String[] args) {
   String str = "hello";
 }
}

 


 

两者生成的bytecode的图示如下:

左边的bytecode中 NEW java/lang/String 创建了第一个String对象;

LDC "hello"

INVOKESPECIAL  java/lang/String.<init> 调用了String的构造函数,创建了第二个String对象;

而右边只有

LDC “hello” 

从两者的bytecode来看new String("...")的形式比"..."的形式的确多产生了一个String对象.

答案在<深入java虚拟机中>:

java为了效率的考虑,使用"...."的方式的字符串会在编译时直接放入到文字池中,而运行时文字池成为了常量池的一部分.使用文字池的好处在于:对于相同的字符串常量会进行合并,在文字池中只占用一个空间.

String a = "hello";
  String b = "hello";
  System.out.println(a==b);

由上可知:代码输出结果 true

而对于new String("....")的形式,本来"..."已经就是一个字符串对象,并存在于文字池中,而new String()会将文字池中的"...."拷贝到堆(heap)中,并把堆(heap)中对象的引用交给字符串引用变量.所以这条语句会产生两个String对象.

String c = new String("hello");
  String d = new String("hello");
  System.out.println(c==d);

由上可知:代码输出结果为 false,引用变量c,d分别指向的是堆(heap)中不同的字符串对象.

 

参考资料:

<effective java>实践31 p107

<深入java虚拟机>

[注]eclipse使用Bytecode Outline插件,以便查看java源文件的bytecode.参考:http://dev2dev.bea.com.cn/bbsdoc/20060123182.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值