详解String对象的内存分配

电子说

1.3w人已加入

描述

String对象有三种创建方式:

第一种方式是直接通过赋值语句,将字符串赋值给String类型的变量。

例如:

String str = “Hello”;

第二种方式是通过new运算符,实例化一个String对象,并将对象引用赋值给String类型的变量。

例如:

String str = new String(“Hello”);

第三种方式是通过String对象的intern()方法返回一个String对象的引用。

例如:

String str = “Hello”。 intern();

前面String对象的三种创建方式,虚拟机对其内存分配上是有所区别的,先来看第一种创建方式。

第一种创建方式是通过赋值语句直接将字符串赋值给String类型的变量。在这种创建方式中,虚拟机会在方法区的常量池中判断是否存在具有和字符串(如Hello)内容相同的String对象:如果常量池不存在和赋值字符串内容相同的对象,虚拟机就在常量池中分配内存并创建该String对象,并将String对象的引用赋值给String类型的变量;如果常量池存在与赋值字符串内容相同的对象,虚拟机会直接将该对象的引用赋值给String类型的变量。这种创建方式对连续创建同一字符串内容的String对象特别有用,内存利用效率非常高效。

第二种创建方式是通过new运算符实例化String对象,并将new运算符返回的对象引用赋值给String类型的变量。在这种创建方式中,虚拟机会创建两个String对象:一个String对象是在常量池中创建,如果常量池中已有字符串内容相同的对象,则不创建;一个String对象是在运行数据区的堆中创建,将在常量池中创建的String对象的字符数组复制到在堆中创建的String对象。

String类型的变量接收new运算符返回的对象引用后,如果使用赋值语句对该String类型的变量重新赋予不同的字符串内容,该变量将会指向一个新的String对象,该String对象会在常量池中创建。

案例1:建立StringTest1类,在类的main()方法内部,使用new运算符实例化一个String对象,返回的对象引用赋值给String类型的变量str,输出str指向对象的哈希码,然后使用赋值语句将新的字符串内容赋值给str,输出str指向对象的哈希码,验证哈希码是否一致。

在memory包下新建StringTest1类。代码如下:

publicclassStringTest1 {

/**

* @Title: main

* @Description: Java程序入口main方法

* @param@paramargs 参数

* @returnvoid 返回类型

* @throws

*/

publicstaticvoidmain(String[] args) {

// 实例化String对象

String str = newString(“Hello”);

System.out.println(“str对象的哈希码:” + str.hashCode());

// 修改str对象的内容

str = “Hello World”;

System.out.println(“str对象修改后的哈希码:” + str.hashCode());

}

}

程序执行结果如下图所示:

从程序的执行结果可以看出,当对str重新赋值不同的内容后,虚拟机会在常量池创建一个新的String对象,并将该对象的引用赋值给str。

第三种创建方式是通过String对象的intern()方法来返回一个String对象的引用。在这种创建方式中,虚拟机会首先判断在常量池中是否存在“Hello”字符串对象,如果存在就直接返回该对象的引用,否则就在常量池创建该对象,并返回对象的引用。

前面String对象的内存分配经常用到常量池,常量池是虚拟机从运行数据区的方法区划分出来的一块内存区域,JDK1.8将常量池放置到运行数据区的堆区域。常量池主要用来存储字面常量、使用final修饰的变量以及符号引用。字面常量包括数值常量(如36、100等)、字符串常量(如“123”、“abc”等)。符号引用是指用一组符号来描述引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。例如编译器会把对象的引用作为一个符号引用,因为编译器不知道对象引用在内存的实际地址,当虚拟机加载类到运行数据区并初始化类后,虚拟机会把这些符号引用转换为直接引用(指向目标的内存地址,如对象在堆中的内存地址)。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分