zoukankan      html  css  js  c++  java
  • new String("abc"),到底在不在常量池中存储"abc"?

    String str = new String("Hello World");

    问之:这行代码到底有没有在字符串常量池中创建“Hello World”字符串呢?

    答曰:有。

    问之:为什么?

    答曰:先看String类的构造函数。

    public String(String original){
                //body
    }

    在这个过程中,“Hello World"作为形参传递给original,这个过程相当于 String original = “Hello World",因此,在常量池中创建字符串“Hello World"。

    之后,我们都知道,new的对象都存在在堆中,因此,new String(“Hello World")在堆中创建了对象,并将其赋值给str,即 String str = 。

    这么一来,在字符串常量池中存在字符串“Hello World",在堆中存在对象“Hello World"。

    然鹅, str == s 并不为true。因为字符串常量池在方法区中(在JDK 1.8之后就放在堆中开辟的一块内存中了),new的对象在堆中,方法区与堆是不同的内存空间。

    因此, str == s为false。

    String str = new String("Hello World");
    String s = "Hello World";

    问曰:不是有个intern()函数吗?

    答之:Of course。

    问曰:那下面的代码str == s 返回true了吗?

    String str = new String("Hello World");
    str.intern();
    String s = "Hello World";

    答之:Of course not。因为前面已经说过了,String str = new String(“Hello World");语句已经在常量池中创建了“Hello World",那么str.intern();就不起作用啦。所以,等效于不加这一句。

    问曰:那str.intern();就是鸡肋了吗?

    答之:存在即合理。请往下看

    String str = new String("Hello") + new String(" World");
    str.intern(); // 注意这一行的顺序,要在下一行之前。否则,也不起作用啦。
    String s = "Hello World";

    好了,这次终于返回true了(在JDK1.7及以后),因为,常量池中虽然存在"Hello"和" World",但是不存在"Hello World",这个只有在堆中存在。

    JDK 1.7以后,在堆中存在而不在常量池中存在的字符串,在常量池中存放其引用,因此str和指向同一块内存。

    JDK 1.7以前,由于常量池不在堆中,那么存放的还是字符串本身,因此仍返回false。

    【大写加粗】以上是参考一些资料和自己的思考,欢迎批评指正。

  • 相关阅读:
    神经网络训练收敛的解决办法
    minSdkVersion
    onlyoffice使用
    linux系统磁盘不足处理方法
    编辑docker容器中的文件
    如何使用Java获取上传图片需要旋转的角度且获取正确方向的图片
    Java数据类型转换
    bat脚本实现jdk安装、环境变量添加及jar包运行
    java实现文件上传接口及java调用文件上传接口
    flutter常用问题查询
  • 原文地址:https://www.cnblogs.com/peony-jing/p/13436686.html
Copyright © 2011-2022 走看看