• 都啥时候了 , 不会有人还搞不懂new String(“abc“)创建了几个对象吧?快看看吧!


    微信公众号 :猿人刘先生(可以看看 写在最后的内容)

    前言

    new String(“abc”);创建了几个对象?等这一类问题是我们经常讨论的问题, 同时也是面试常问到的问题, 我们都知道在Java中从”.java"文件编译成".class"文件的过程,会有一个优化器去优化我们的代码, 为了彻底搞清楚这一类问题, 我们还得从底层原理开始分析.

    JVM简介

    JVM,全称Java Virtual Machine(Java虚拟机),是一个规范,用于在实际的计算机上仿真模拟各种计算机功能。它是一个虚构出来的计算机。JVM是执行代码并为该代码提供运行时环境的软件程序的规范。

    具体来说,Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收器等组件。这些组件共同构成了JVM的运行环境。此外,JVM还包括内存区域,如程序计数器(线程私有)、虚拟机栈(线程私有)、本地方法区(线程私有)、堆(Heap-线程共享)和方法区/永久代(线程共享)等。

    这篇文章重点涉及到的还是堆(Heap-线程共享)和栈(虚拟机栈(线程私有),

    栈简介

    栈内存则是用于存储方法调用、局部变量等运行时信息。栈内存遵循LIFO(后进先出)原则,一旦线程创建,就会在栈上为它的参数和局部变量分配空间。当线程执行完毕返回时,那些在栈上分配的内存空间会自动被释放,这一特性使得栈的管理变得相对容易。栈内存的大小在编译时期就已经被确定下来,所以它是一个相对较小的固定内存区域。并且,由于栈内存的分配和释放由编译器逐行执行,速度相对较快。

    堆简介

    堆内存是Java中用于存储对象实例和数组的内存空间。当我们使用new关键字创建一个对象或者创建一个数组的时候,就会在堆内存中分配一段连续的内存空间来存储这个对象或者数组。该空间可以根据需要进行动态分配和释放,而且在生命周期上与应用程序相同,只有在应用程序退出或对象被明确销毁后,才会被回收。但需要注意的是,由于堆内存需要在运行时动态分配,因此其存取速度较慢。

    字符串常量池

    在Java中,字符串常量池是一块特殊的内存区域,用于存储字符串对象。这是由于Java中的字符串是不可变的,一旦创建后不能被修改。为了提高性能和节省内存空间,Java引入了字符串常量池的概念来管理这些字符串对象。

    当需要创建一个字符串对象时,Java会首先检查字符串常量池中是否已经存在相同内容的字符串对象。如果存在,则直接返回该对象的引用,而不会重新创建新的对象。这种机制可以避免重复创建相同内容的字符串,从而减少内存占用。

    此外,由于字符串常量池中的字符串对象是唯一的,所以可以通过比较对象的引用地址来判断两个字符串是否相等,而不必逐个字符进行比较。这进一步提高了字符串比较的效率。
    值得注意的是,Java中有几种不同的常量池,包括类常量池、字段常量池、方法常量池等。其中,字符串常量池是存储在Java堆内存中的。这是JVM为了提高性能和减少内存开销,在实例化字符串常量时进行的一些优化设计。

    情况一

    String a = “abc”;

    分析

    如果此时堆内存中的字符串常量池是没有abc这个字符串对象的, 此时会先在字符串常量池中创建"abc"这个字符串对象, 然后将这个字符串对象的引用(地址)压入栈中; 如果此时堆内存中的字符串常量池有abc这个字符串对象, 那就是直接将这个字符串对象的引用(地址)压入栈中;
    所以 : 当字符串常量池有abc这个字符串对象时 , 创建了0个对象 , 没有abc这个字符串对象时创建了一个1对象

    内存情况

    情况二

    String a = “a” + “b”;

    分析

    这里可能很多人都会有一个误解 , 就是创建了3个对象, "a"一个, "b"一个, “a” + “b"又是一个, 其实这种想法是错误的, 因为编译器在编译的时候就会把"a” + "b"进行拼接, 然后再去判断常量池中是否有"ab"这个字符串对象, 如果有就把这个对象的引用(地址压入栈中), 如果没有的话, 就会创建"ab"这个字符串对象, 然后把这个对象的地址压入栈中.
    所以 : 当字符串常量池有ab这个字符串对象时 , 创建了0个对象 , 没有ab这个字符串对象时创建了一个1对象

    内存情况

    情况三

    String a = “abc”;
    String b= “a” + “b” + “c”;
    System.out.println(a == b);

    分析

    在以上的两种情况中, 有个共同的点 , 就是如果存在的话就是创建了0个对象, 否则的话就是1个对象 , 所以这种情况就比较好理解了, 因为字符串常量池中没有"abc"这个对象, 所以会先进行创建, 然后"a" + “b” + “c"经过编译器拼接之后为"abc”, 在字符串常量池中有了, 所以不必创建, 那么在这个过程中, 创建了1个对象 , 并且a == b为true, 因为地址是相同的 , 都是"abc"这个对象的地址

    内存情况

    情况四

    String a = “h”;

    String b = “he”;
    String c = a + “e”;

    分析

    前两行代码也是相同的逻辑, 如果h存在字符串常量池 ,则不创建,如果不存在, 则创建 , 如果he存在字符串常量池 ,则不创建,如果不存在, 则创建, 第三行代码需要注意的是 :a + “e” , "e"存在字符串常量池 ,则不创建,如果不存在, 则创建, a + “e” 这个运算的过程会在编译时期被编译器编译为使用StringBuilder拼接,所以一共至是多4个对象 , 分别为常量池中 : “h” ,“he” , “e” , 以及堆内存中StringBuilder

    内存情况

    情况五

    String a = “h”;
    String b = “he”;
    String c = a + “e”;
    String d = “h” + “e”;
    System.out.println(c == d);
    System.out.println(b == d);

    分析

    经过上面几种情况的分析,这个过程也是最多创建4个对象 , 变量c引用的是堆内存中new StringBuilder()的地址, 变量d引用的是字符串常量池中"he"的地址 ,因为"he"在编译时通过第二行代码就被写入了常量池,
    所以说c == d为false , b == d为true

    内存情况

    情况六

    String a = new String(“a”);

    分析

    这个就比较简单了,如果"a"存在字符串常量池则不创建,如果不存在则创建,然后new String在堆中申请了一块内存,所以至多是创建了2个

    内存情况

    情况七

    String a = new String(“a”) + new String(“b”);

    分析

    这个先说答案吧,创建了6个对象,分别为字符串常量池"a" , “b” , new String()的两个,还有一个就是编译器会优化,也是同样的会创一个StringBuilder对象来拼接,那么这个StringBuilder就是第五个,拼接之后,调用toString()方法,又生成一个字符串“ab“, 所以说一共至多是6个对象,字符串常量池中三个 : “a” , “b” , “ab” , 堆中两个new String();一个一个new StringBuilder();

    内存情况


    如何在IDEA中使用字节码查看工具
    首先需要在idea中进行如下配置

    然后再想要查看的文件中右键


    每次更改代码之后需要重新运行 , 然后进行步骤2

    写在最后

    如果您觉得这些文章对您有所启发和帮助,何不将它们与您的好友分享呢?这样,他们也能够享受其中的精彩内容,并从中获得启发。谢谢您的支持与分享!~
    同时也希望您用发财的手帮忙点个关注,可以通过下方菜单点击福利领取上千套简历模板、几千道的面试题pdf以及几百G涵盖了Java开发,前端开发,小程序开发,数据库,测试等等的相关学习书籍与资料。
    微信公众号 :猿人刘先生

    另外也可以通过点击交流群按钮添加我好友,然后拉您到自己的创建的Java知识分享群。一起去讨论、学习、成长、进步,谢谢~

  • 相关阅读:
    三西格玛和六西格玛区别是什么?优思学院用一幅图告诉你
    代码整洁之道
    缓存更新策略
    嵌入式开发板 ~ 说明
    LeetCode:3. 无重复字符的最长子串
    腾讯云免费SSL证书申请流程(图文教程)
    华为三层交换机:ACL的基本实验
    Ablebits Ultimate Suite for Excel
    13、【创业必备企业架构,可开发任意项目】SpringCloud大型企业分布式微服务云架构源码之MySQL 分组
    (成功最详细版本,自定义传参失败,跳转出现空白页面,校验文件失败)微信小程序扫码跳转小程序指定页面保姆级教程
  • 原文地址:https://blog.csdn.net/qq_45001002/article/details/134457813