Java中的字符串常量池(图解)

创建字符串对象有两种方式
一种是通过初始化的方式创建

String str="Hello";

另一种是使用new关键字创建

String str = new String("Hello");

Java为了避免产生大量的字符串对象,设计了一个字符串池(String Pool),通过初始化方式创建的字符串对象都会存在于字符串池中,且字符串池中的字符串不会重复,以便可以被共享使用,提高存储效率。

其工作原理是:

当使用初始化的方式创建对象时,JVM会首先检查字符串池中是否存在值相等的字符串,如果存在,则不进行创建,而是直接返回字符串池中该字符串的引用地址。如果不存在,则创建该对象,并放入字符串池中,返回新创建的字符串的引用地址。

当使用new关键字创建对象时,JVM仍然首先检查字符串池中是否存在要创建的字符串,如果不存在,则在字符串池中创建一个字符串对象,然后在堆内存中继续创建一个字符串对象,返回该对象的引用地址。如果存在,则只在堆内存中创建一个字符串对象,返回该对象的引用地址。

使用new关键字创建字符串对象,实际上调用了String类的构造函数,构造函数的源码如下:

public String(String original) {

  this.value = original.value;

  this.hash = original.hash;

}

从上述代码可以看出,构造函数需要传入一个String对象,然后将该对象的值作为当前对象的值。因此,执行代码String str = new String(“Hello”);时,如果字符串池中不存在字符串“Hello”,则会创建两个对象,因为字符串“Hello”本身就是一个对象,通过关键字new又创建了一个对象。

详解+实例!

String str1 = new String("Hello");①

String str2 = new String("Hello");②

String str3 = "Hello"; ③

String str4 = "Hello"; ④



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

System.out.println(str3 == str4); //true

System.out.println(str2 == str3); //false



System.out.println(str1.equals(str2)); //true

System.out.println(str3.equals(str4)); //true



String str5=str4;⑤

System.out.println(str4 == str5); //true



str5="World";⑥

System.out.println(str4);//Hello

System.out.println(str5);//World

当代码运行到第①行后,JVM首先会查找字符串池中是否存在值为“Hello”的对象,发现不存在,则在字符串池中创建一个“Hello”对象,在堆内存中也创建一个“Hello”对象,并将堆内存中的“Hello”对象的引用(内存地址)赋给变量str1,此时字符串在内存中的存储示意图如下:

String str1 = new String("Hello");

字符串在内存中的存储示意图

Java中的字符串常量池(图解)_第1张图片

当代码运行到第②行后,JVM首先会查找字符串池中是否存在值为“Hello”的对象,发现存在,则只在堆内存中创建一个值为“Hello”的对象,此时字符串在内存中的存储示意图如下:

String str2 = new String("Hello");

字符串在内存中的存储示意图

Java中的字符串常量池(图解)_第2张图片

当代码运行到第③行后,JVM首先会查找字符串池中是否存在值为“Hello”的对象,发现存在该对象,则将该对象的引用赋给变量str3,此时字符串在内存中的存储示意图如下:

String str3 = "Hello";

字符串在内存中的存储示意图
Java中的字符串常量池(图解)_第3张图片

当代码运行到第④行后,同理,会将“Hello”对象的引用赋给变量str4。

String str4 = "Hello";

当代码运行到第⑤行后,会将str4的引用赋给str5,

String str5=str4;

字符串在内存中的存储示意图
Java中的字符串常量池(图解)_第4张图片

当代码运行到第⑥行后,JVM会首先查找字符串池中是否存在值为“World”的对象,发现不存在,则创建一个“World”对象,并将该对象的引用赋给变量str5,此时字符串在内存中的存储示意图如下:

str5="World";

字符串在内存中的存储示意图

Java中的字符串常量池(图解)_第5张图片

到此,str5的引用是对象“World”;str4和str3的引用是同一个对象“Hello”;str2和str1的引用是不同的对象“Hello”。

你可能感兴趣的:(字符串,java,jvm)