String str = new String("abc")究竟创建了几个对象?

先给出答案:两个。(如果原来常量池中没有"abc")

String是一个特殊的包装类数据。即可以用String str = new String("abc");的形式来创建,也可以用String str = "abc";的形式来创建

String str = "abc"创建对象的过程

  1. 首先在常量池中查找是否存在内容为"abc"字符串对象
  2. 如果不存在则在常量池中创建"abc",并让str引用该对象
  3. 如果存在则直接让str引用该对象


"abc"是怎么保存,保存在哪?

常量池属于类信息的一部分,而类信息反映到JVM内存模型中是对应存在于JVM内存模型的方法区,也就是说这个类信息 中的常量池概念是存在于在方法区中。

而方法区是在JVM内存模型中的堆中由JVM来分配的,所以"abc"可以说存在于堆中(而有些资料,为了把方法区的 堆区别于JVM的堆,把方法区称为栈)。一般这种情况下,"abc"在编译时就被写入字节码中,所以class被加载时,JVM就为"abc"在常量池中 分配内存,所以和静态区差不多。


String str = new String("abc")创建实例的过程

  1. 首先在堆中(不是常量池)创建一个指定的对象"abc",并让str引用指向该对象
  2. 在字符串常量池中查看,是否存在内容为"abc"字符串对象
  3. 若存在,则将new出来的字符串对象与字符串常量池中的对象联系起来
  4. 若不存在,则在字符串常量池中创建一个内容为"abc"的字符串对象,并将堆中的对象与之联系起来

我们来看以下两个例子加深理解:

String str1 = "abc"; String str2 = "ab" + "c"; str1==str2是true吗?

答案:是。因为String str2 = "ab" + "c"会查找常量池中时候存在内容为"abc"字符串对象,如存在则直接让str2引用该对象,显然String str1 = "abc"的时候,上面说了,会在常量池中创建"abc"对象,所以str1引用该对象,str2也引用该对象,所以str1==str2

String str1 = "abc"; String str2 = "ab"; String str3 = str2 + "c"; str1==str3是false吗?

答案:是。因为String str3 = str2 + "c"涉及到变量(不全是常量)的相加,所以会生成新的对象,其内部实现是先new一个StringBuilder,然后 append(str2),append("c");然后让str3引用toString()返回的对象

猜你喜欢

转载自blog.csdn.net/qq_36470686/article/details/83444483
今日推荐