「Java技术探索」带你进入String类的易错点和底层本质分析

本文深入探讨了Java中String类的常见易错点,包括字符串拼接与创建的不同场景分析,以及String、StringBuilder、StringBuffer的性能对比。文章还详细介绍了字符串常量池、垃圾收集、intern方法的工作原理,并通过不同JDK版本的差异展示了String.intern()的实际应用。此外,解释了字符串创建和拼接的内部机制,以及字符串对象在静态常量池、运行时常量池和堆中的交互过程。
摘要由CSDN通过智能技术生成

字符串拼接及创建的案例分析

案例一

String a = "test";
String b = "test";
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1639705018
  • 当a初始化时,"test"对象被加入字符串常量池,b初始化时,检查到"test"对象在字符串常量池中,则直接指向该对象
  • a.equals(b)比较的是对象持有的内容,显然为true,a==b比较的是是否指向的是同一对象,因为指向的同为字符串常量池中"test"对象,结果为true
  • System.identityHashCode方法的返回值为参数对象object中hashCode()的返回值,无论hashCode()方法是否被覆盖

案例二

String a = "test";
String b = new String("test");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
  • 当a初始化时,"test"对象被加入字符串常量池,b初始化时,首先检查到"test"对象在字符串常量池中,无需在字符串常量池中创建对象,然后在堆中创建"test"对象,b指向堆中"test"对象
  • 可得a.equals(b)为true,a==b为false

案例三

String a = new String("test");
String b = new String("test");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
  • 当a初始化时,"test"对象被加入字符串常量池,然后在堆中创建"test"对象,a指向堆中"test"对象
  • b初始化同a,但是不像字符串常量池中那样,虽然a与b的内容相同,但是依然会在堆上创建两个对象;
  • 所以a.equals(b)为true,a==b为false

案例四

String a = "test";
String b = "te"+"st";
System.out.println(a.equals(b)); // true
System.out.println(a == b); // true
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1639705018

与案例一不同的是,b的值由两个引号相加所得,但是结果和案例一是一样的,a与b指向的都是字符串常量池中的同一对象,这是因为形如"te"+"st"这种由多个字符串常量连接而成的字符串在编译期被认为是一个字符串常量

案例五

String a = new String("test");
String b = new String("te") + new String("st");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(b)); // 1627674070
  • 根据案例三中的分析可知,a与b内容是一致的,但是指向的不是同一对象,但是问题是这个案例中会在字符串常量池中创建多少个对象?
  • 答案应该是三个:“test”、“te”、“st”;在堆上会创建多少个对象?答案是四个:a指向的"test"对象,两个匿名对象"te"、“st”,b指向的"test"对象

案例六

String a = "test";
String b = "te";
String c = "st";
String d = b + c;
System.out.println(a.equals(d)); // true
System.out.println(a == d); // false
System.out.println(System.identityHashCode(a)); // 1639705018
System.out.println(System.identityHashCode(d)); // 1627674070
<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾听铃的声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值