对于String的认识

本文通过分析Java中String字符串对象的创建、管理及操作符‘+’的使用,解释了String对象在堆内存中的创建过程、StringPool的概念、不同赋值语句创建对象的数量和位置,以及intern()方法的作用。通过示例代码,直观展示了Java如何高效地管理和利用String资源。

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

这段时间有不少关于String的帖子,也有很多很好的解释。我在这里就算是搜集一下,并简单地分析一下原因。一是我不熟悉JVM的底层规范,二是我觉得别人分析的很好,但是不能拘泥于这样分析,分析的目的是为了让我们明白其中的道理。
下面我列出参考的帖子,也方便大家去查看:

《深入研究java对String字符串对象的创建以及管理》

《操作符“+”的定义,他是否是new了一个新的字符串?》

《到底创建了几个String对象?》

还是靠程序来说话:

  1. public class VerifyString {
  2.     public static void main(String args[]){
  3.         String str1 = "I am a String";
  4.         String str2 = "I am a String";
  5.         String str3 = new String("I am a String");
  6.         String str5 = "I am a ";
  7.         String str6 = "String";
  8.         String str7 = str5 + str6;
  9.         String str8 = "I am a " + "String";
  10.         String str9 = str3.intern();
  11.         String str10 = str7.intern();
  12.         
  13.         if(str1 == str2)
  14.             System.out.println("str1 and str2 are the same String.");
  15.         else
  16.             System.out.println("str1 and str2 are the different Strings.");
  17.         
  18.         if(str1 == str3)
  19.             System.out.println("str1 and str3 are the same String.");
  20.         else
  21.             System.out.println("str1 and str3 are the different Strings.");
  22.         
  23.         if(str1 == str7)
  24.             System.out.println("str1 and str7 are the same String.");
  25.         else
  26.             System.out.println("str1 and str7 are the different Strings.");
  27.         
  28.         if(str1 == str8)
  29.             System.out.println("str1 and str8 are the same String.");
  30.         else
  31.             System.out.println("str1 and str8 are the different Strings.");
  32.         
  33.         if(str1 == str9)
  34.             System.out.println("str1 and str9 are the same String.");
  35.         else
  36.             System.out.println("str1 and str9 are the different Strings.");
  37.         
  38.         if(str1 == str10)
  39.             System.out.println("str1 and str10 are the same String.");
  40.         else
  41.             System.out.println("str1 and str10 are the different Strings.");
  42.         
  43.     }
  44. }

运行的结果是:

  1. str1 and str2 are the same String.
  2. str1 and str3 are the different Strings.
  3. str1 and str7 are the different Strings.
  4. str1 and str8 are the same String.
  5. str1 and str9 are the same String.
  6. str1 and str10 are the same String.

解释以上的输出结果,首先要理解一个叫String Pool的概念,虽然JVM没有明确提出这个概念,但是细想一下,别的语言String基本都是作为基本类型来处理的,而在Java中直接就是一个对象,然而奇怪的是对象能像基本类型那样直接赋常量。这就能看出Java设计者的那种取舍吧,毕竟作为对象来处理的话,效率没有基本类型那样高。我们不需要更多的理解,直接记住String str1 = "I am a String";是把"I am a String"扔到了字符串池中,然后把引用抛给str1,以后再有相同值的String变量也是这种赋值语句的,那么还是存在字符串池中,有就直接返回引用,没有就创建一个新的。所以说着语句就创建了一个String对象。再看下一个String str3 = new String("I am a String");这个创建了几个对象?两个!不要怀疑!一个是在new String("I am a String")创建在heap中的,另一个是str3也在heap中,它们所指向的字符数组是相同的,位于内存区的常量池中。关于这一点,请看大企鹅的这篇blog:《 还是 String》。接下来看str7和str8,明明两个的值是一样的,为什么结果不一样呢?这就牵扯到Java编译器对于不同str8的优化了。因为str7右边的是两个变量,而不是直接的两个值,编译器就无法在编译期间知道str8的值,相反,str8对于编译器来说直接就是str8 = "I am a String"了,这样的两种不同的情况,就有不同的结果了。再看str3和str7都和返回否定的,而为什么str9和str10返回的是一致的呢?因为intern()方法是把执行该方法的引用拖到了字符串池中,当然了如果字符串池中有的话,就直接返回引用了。

总结一下就是:
1. 区分好String str1 = "I am a String"和String str3 = new String("I am a String")创建对象的数目和地方。
2. 了解String str1 = "I am a " + "String"是编译期间确定值的。
3. 了解intern()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值