Java中String的到底存在哪里???

Java中String的到底存在哪里???

目录

一、堆与字符串常量池

二、Java创建字符串对象的两种方式

1. 字面值方式创建字符串对象

2. 使用new关键字创建字符串对象

三、经典面试问题之创建了几个对象?

1. String s1 = "11";

2. String s1 = "1" + "1";

3. String s1 = new String("11");

4. String s1 = new String("1") + new String("1");

四、String.intern()的作用

1. 如果常量池中已经存在该值

2. 如果常量池中不存在该值

一、堆与字符串常量池

堆是Java虚拟机中存储对象实例和数组的内存区域。 字符串常量池(String Pool)是Java虚拟机在内存中专门为字符串字面量分配的一块区域。它用于存储所有用双引号声明的字符串常量,以及运行期间调用intern()方法生成的字符串。常量池中的相同内容的字符串只会保存一份,多个引用会指向同一个对象,从而节省内存并提高效率。、

字符串池的实现有一个前提条件:String对象是不可变的。因为这样可以保证多个引用可以同时指向字符串池中的同一个对象。如果字符串是可变的,那么一个引用操作改变了对象的值,对其他引用会有影响,这样显然是不合理的。

二、Java创建字符串对象的两种方式

1. 字面值方式创建字符串对象

public static void main(String[] args) {

String str1 = "aaa";

String str2 = "aaa";

System.out.println(str1 == str2); // 输出 true

}

当使用字面值(如"aaa")创建字符串时,JVM会先在字符串常量池中查找是否存在该字符串对象。如果不存在,则在常量池中创建,并返回其引用。如果已存在,则直接返回常量池中该对象的引用。因此,str1和str2都指向常量池中的同一个"aaa"对象,str1 == str2结果为true。

2. 使用new关键字创建字符串对象

public static void main(String[] args) {

String str1 = new String("aaa");

String str2 = new String("aaa");

System.out.println(str1 == str2); // 输出 false

}

使用new String("aaa")时,JVM会先检查常量池中是否有"aaa"对象。如果没有,先在常量池中创建"aaa"对象。然后,无论常量池中是否有"aaa",都会在堆内存中新建一个"aaa"对象,并返回堆对象的引用。每次new String("aaa")都会在堆中创建新的对象,因此str1和str2指向不同的堆对象,str1 == str2结果为false。

三、经典面试问题之创建了几个对象?

1. String s1 = "11";

"11"是字符串字面量,存储在字符串常量池中。s1指向常量池中的"11"对象。创建对象数量:1(常量池1个)。

2. String s1 = "1" + "1";

"1" + "1"在编译期会被优化为"11",等价于String s1 = "11"。创建对象数量:1(常量池1个)。

3. String s1 = new String("11");

new String("11")会在堆上创建一个新的String对象,内容为"11"。常量池中也有"11"(因为字面量被用来创建堆对象)。s1指向堆上的"11"对象。创建对象数量:2(常量池1个,堆1个)。

4. String s1 = new String("1") + new String("1");

new String("1")会在堆上创建两个新的String对象,各自内容为"1",但常量池中也有"1"。+操作会在堆上创建一个新的String对象,内容为"11"。结果:s1指向堆上的"11",常量池中也有"1",但没有"11"。创建对象数量:4(常量池1个,堆3个)。

四、String.intern()的作用

intern() 的作用是确保常量池中有该字符串的唯一引用,并返回该引用:

1. 如果常量池中已经存在该值

intern() 会直接返回常量池中已有的字符串引用,不会加入当前对象。

String a = "abc";

String b = new String("abc");

System.out.println(b.intern() == a); // true

这里常量池中已有 "abc",b.intern() 返回的就是 a 指向的常量池对象。

2. 如果常量池中不存在该值

intern() 会把当前字符串对象的引用放入常量池,并返回该引用。

String s1 = new String("x") + new String("y");

System.out.println(s1.intern() == s1); // true

因为 "xy" 不在常量池中,intern() 把 s1 的引用放入池中,所以返回 s1 本身。

相关数据

365bet体育在线官 恒组词(113个词语)

恒组词(113个词语)

08-30 访问量: 8685
365bet体育在线官 怎么发说说才不会显示手机的型号 发说说
beat365在线体育正规吗 世界杯欧洲区预选赛规则详解及参赛队伍晋级机制解析