首页 > 其他分享 >关于常量池的分析

关于常量池的分析

时间:2022-11-08 20:34:05浏览次数:39  
标签:分析 ab String s1 池中 关于 字符串 常量

关于常量池的分析

第一种情况

public class Dome {
    public static void main(String[] args) {
        String s1 = "ab";
        String s2 = "ab";
        System.out.println(s1 == s2);

    }
}
//ture

对应的内存分析图

第二种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = "a" + "b";
        String s2 = "ab";
        System.out.println(s1 == s2);

    }
}
//ture

内存图分析:

编译器会进行优化,在编译阶段会把“a”,"b",优化成
字符串“ab”,然后再类加载阶段,把ab字符串纳入到
字符串常量池中。

第三种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = new String("a") + new String("b");
        //会在堆中创建一块新的空间,并将该空间的地址执行栈中引用这个字符串的变量
        s1.intern();
        String s2 = "ab";
        System.out.println(s1 == s2);
    }
}//ture

内存图分析:

当调用s1.intern()方法的时候,会做以下判断
查看当前字符串("ab")在常量池中是否存在
①:存在

若栈中有引用,则返回该字符串(“ab”)在常量池中的地址给栈中引用这个字符串的变量。
若栈中没有引用,则什么也不做。

②:不存在

直接将堆中(不是字符串常量池中)该字符串的地址复制到字符串常量池中,这
样字符串常量池就有了该字符串的地址引用,也可以说此时字符串常量池中的字
符串只是一个对 堆中字符串对象的引用,它们两个的地址相同,然后再把这个地
址返回给栈中要引用这个字符串的变量。

第四种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = new String("ab");
        s1.intern();
        String s2 = "ab";
        System.out.println(s1 == s2);
    }
}
//false

内存图分析

当执行第一行代码的时候,首先去常量池中找字符串“ab”。

如果找到了,则不在字符串常量池中创建一个新对象,直接将堆引用指向字符
串“ab”在常量池中的地址。

如果找不到,此时在堆中和常量池中都会创建该字符串的对象,但是他们地址不
同,一个是堆中对象的地址,一个是字符串常量池中的地址。并让堆中的引用指
向字符串常量池中的地址。

调用intern()方法之前,此时常量池中已经有“ab”,并且栈中
没有任何引用。因此,什么也不做。

当执行第三行代码的时候,因为此时常量池中已经有字符串“ab”,所以此步只是把new
String("ab")在常量池中创建“ab”对象的地址赋值栈中引用s2。

第五种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = new String("ab");
        String s3 = s1.intern();
        String s2 = "ab";
        System.out.println(s3 == s2);
    }
}
//ture

内存图分析

当执行第一行代码的时候,首先去常量池中找字符串“ab”。

如果找到了,则不在字符串常量池中创建一个新对象,直接将堆引用指向字符
串“ab”在常量池中的地址。
如果找不到,此时在堆中和常量池中都会创建该字符串的对象,但是他们地址不
同,一个是堆中对象的地址,一个是字符串常量池中的地址。并让堆中的引用指
向字符串常量池中的地址。
调用intern()方法之前,此时常量池中已经有“ab”,但是栈中
有引用s2,因此,将常量池中的地址返回给s2
当执行第三行代码的时候,因为此时常量池中已经有字符串“ab”,所以此步只是把new
String("ab")在常量池中创建“ab”对象的地址赋值栈中引用s3。

第六种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = new String("a") + "b";
        String s3 = s1.intern();
        String s2 = "ab";
        System.out.println(s3 == s1);
    }
}//ture

内存图分析

第七种情况

public class Dome {

    public static void main(String[] args) {
        String s1 = new String("a") + "b";
        String s2 = "ab";
        String s3 = s1.intern();
        System.out.println(s3 == s1);
    }
}//false

内存图分析

标签:分析,ab,String,s1,池中,关于,字符串,常量
From: https://www.cnblogs.com/xuzhidong/p/16871063.html

相关文章

  • 系统调用捕获和分析—使用LKM方法添加系统调用
    本文为毕业设计过程中学习相关知识、动手实践记录下来的完整笔记,通过阅读本系列文章,您可以从零基础了解系统调用的底层原理并对系统调用进行拦截。由于本人能力有限,文章中可......
  • 系统调用捕获和分析—Ring0层kprobe劫持系统调用
    本文为毕业设计过程中学习相关知识、动手实践记录下来的完整笔记,通过阅读本系列文章,您可以从零基础了解系统调用的底层原理并对系统调用进行拦截。由于本人能力有限,文章中可......
  • 系统调用捕获和分析—修改内核方法添加系统调用
    本文为毕业设计过程中学习相关知识、动手实践记录下来的完整笔记,通过阅读本系列文章,您可以从零基础了解系统调用的底层原理并对系统调用进行拦截。由于本人能力有限,文章中可......
  • 关于自动部署 - 基于gitlab关联 腾讯云 web 应用
    gitlab相当于gitee的企业版形式; 步骤1.使用Vscode编写代码,使用gitlab托管代码,2.新建腾讯云web应用,gitlab关联web应用,3.每次push代码到gi......
  • C#关于微软flowDocument不显示png图片的Bug
    C#关于微软​​flowDocument​​​不显示​​png​​图片的Bug最近再用WPF​​flowDocument​​​做文档。文档中需要引用图片。开始时引入的是​​png​​格式的图片。但是......
  • 关于git错误:Git未能顺利结束(退出码 128)的解决办法
      如图:问题原因:主要是:用户名、邮箱、用户密钥跟github官网上配置的不一致https://blog.csdn.net/weixin_52517585/article/details/126922820......
  • 关于如何在Windows下通过Golang调用cmd指令
    太nm操蛋了,我tm弄了两小时。起因目前我的项目中,当并发量提高的时候会出现UDP的bufferqueuefull的情况,我怀疑是因为UDP端口释放太慢导致堆积。于是就打算用golang写一......
  • Python程序调试分析大杀器--pystack-debugger
    分析程序异常某个进程100%,分析思路示例代码#-*-coding:utf8-*-importtimedeftest_1():a=1+1time.sleep(100*10)returnaif__name__=="__m......
  • 分析型数据库
    软件简介TBase具备高性能可扩展的分布式事务能力,支持RC和RR两种隔离级别;通过安全、管理、审计三权分立体系,提供全方位的数据安全保证机制;支持高性能分区表,可使得数据检......
  • 20220926 18. 认识与分析登录文件
    18.1什么是登录文件登录文件可以记录系统在什么时间、哪个主机、哪个服务、出现了什么讯息等信息,这些信息也包括使用者识别数据、系统故障排除须知等信息。如果你能够......