0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

详解String对象的内存分配

如意 来源:百家号 作者:米粒教育 2020-07-01 10:09 次阅读

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”等)。符号引用是指用一组符号来描述引用的目标,符号可以是任何形式的字面量,只要使用时能够无歧义的定位到目标即可。例如编译器会把对象的引用作为一个符号引用,因为编译器不知道对象引用在内存的实际地址,当虚拟机加载类到运行数据区并初始化类后,虚拟机会把这些符号引用转换为直接引用(指向目标的内存地址,如对象在堆中的内存地址)。

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

    关注

    19

    文章

    2903

    浏览量

    102977
  • 内存分配
    +关注

    关注

    0

    文章

    16

    浏览量

    8265
  • string
    +关注

    关注

    0

    文章

    40

    浏览量

    4627
收藏 人收藏

    评论

    相关推荐

    详解单片机的内存分配

    对于初学者而言,对单片机的内存分配往往最让人头疼,很多人学了单片机几年 都不知道单片机内部的内存使用情况是如何分配的。要了解 ROM(flash)、RAM(sram)启动,首先 需要对
    发表于 11-07 10:42 1903次阅读

    单片机的内存分配详解

    对于初学者而言,对单片机的内存分配往往最让人头疼,很多人学了单片机几年 都不知道单片机内部的内存使用情况是如何分配的。要了解 ROM、RAM启动,首先 需要对 链接器 Linker 如
    发表于 03-05 15:00

    对象分配内存错误怎么办

    请大神帮忙,万分感谢!!!操作系统:ucosIII 芯片:STM32F103我的类建立比较多。类对象是指针CCarriage*gCar;分配内存语句:gCar = new CCarriage
    发表于 05-25 09:51

    Linux内存系统: Linux 内存分配算法

    内核中经常使用的对象放到高速缓存中,并且由系统保持为初始的可利用状态。比如进程描述符,内核中会频繁对此数据进行申请和释放2) 内部碎片· 已经被分配出去的的内存空间大于请求所需的内存
    发表于 08-24 07:44

    请问JavaScript字符串对象String是什么?

    字符串对象 String 提供了对字符串进行处理的属性和方法
    发表于 11-05 06:39

    关于RTT支持的内存分配算法

    的融合。 最原始的SLAB算法是Jeff Bonwick为Solaris 操作系统而引入的一种高效内核内存分配算法。 RT-Thread的SLAB分配器实现主要是去掉了其中的对象构造及
    发表于 04-27 14:40

    关于RTT支持的内存分配算法

    的融合。 最原始的SLAB算法是Jeff Bonwick为Solaris 操作系统而引入的一种高效内核内存分配算法。 RT-Thread的SLAB分配器实现主要是去掉了其中的对象构造及
    发表于 04-27 14:42

    java中string不可变的原因

    让s的值为ABCabc, 然后又让s的值为123456。 从打印结果可以看出,s的值确实改变了。那么怎么还说String对象是不可变的呢? 其实这里存在一个误区: s只是一个String对象
    发表于 09-27 13:24 0次下载
    java中<b class='flag-5'>string</b>不可变的原因

    内核内存分配常用函数使用

    区的初始化在平台特定的文件中, 常常在 arch 目录树的 mm/init.c。kamlloc 的使用方法Linux 处理内存分配通过创建一套固定大小的内存对象池.
    发表于 04-02 14:32 897次阅读

    一文详解Java对象内存布局

    这个实例对象是以怎样的形态存在内存中的? 一个Object对象内存中占用多大? 对象中的属性是如何在
    发表于 09-30 14:38 1067次阅读
    一文<b class='flag-5'>详解</b>Java<b class='flag-5'>对象</b>的<b class='flag-5'>内存</b>布局

    什么是堆内存?堆内存是如何分配的?

    在一般的编译系统中,堆内存分配方向和栈内存是相反的。当栈内存从高地址向低地址增长的时候,堆内存从低地址向高地址
    的头像 发表于 07-05 17:58 9497次阅读

    字符串string对象操作的全面总结

        字符串操作看似简单,其实非常重要,不注意的话,经常出现代码运行结果和自己想要的不一致,甚至崩溃。本文总结了一些构建string对象方法、修改string对象的方法、
    的头像 发表于 11-11 11:23 1708次阅读
    字符串<b class='flag-5'>string</b><b class='flag-5'>对象</b>操作的全面总结

    linux内存管理中的SLAB分配详解

    管理区页框分配器,这里我们简称为页框分配器,在页框分配器中主要是管理物理内存,将物理内存的页框分配
    发表于 05-17 15:01 1925次阅读
    linux<b class='flag-5'>内存</b>管理中的SLAB<b class='flag-5'>分配</b>器<b class='flag-5'>详解</b>

    Java中的对象一定在堆中分配

    的。但是,有没有例外呢?Java中的对象一定在堆中分配吗? 接下来,小编带你揭开Java内存模型的神秘面纱。 1、Java内存模型简介 Java内存
    的头像 发表于 09-30 10:19 319次阅读
    Java中的<b class='flag-5'>对象</b>一定在堆中<b class='flag-5'>分配</b>吗

    bigdecimal转string类型避免空指针

    在Java中,BigDecimal是用于处理高精度数字计算的类。它提供了一种有效的方法来避免使用浮点数的精确度损失问题。然而,在将BigDecimal对象转换为String类型时,需要特别小心以避
    的头像 发表于 11-30 11:12 898次阅读