【JVM】对String::intern()方法深入详解(JDK7及以上)

文章目录

  • 1、什么是intern?
  • 2、经典例题解释
    • 例1
    • 例2
    • 例3

1、什么是intern?

String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。----书上描述

已经包含。。。可能不太好理解。我画图解释
在这里插入图片描述
方法的执行顺序肯定是从下向上依次执行的。
String s1 = “11”; 先去字符串常量池中查看是否已经存在“11”,如果存在则直接返回"11"的地址,如果不存在则会在字符串常量池中创建“11”,然后返回创建好的“11”的地址。因为之前未创建过,所以该指令会先去字符串常量池中创建“11”,然后返回11的地址 501
String s2 = new String(“11”); 也是先去字符串常量池中查看是否已经存在“11”,如果有就在堆中创建对象,存的是字符串常量池中“11”的地址501,最后,将堆中对象的地址601返回给S2 。
String s3 = s2.intern(); intern方法会从字符串常量池中,查询当前s2字符串"11"是否存在,若不存在就会在字符串常量池中创建字符串"11"的实例, 由于s1已经在字符串常量池中已经创建了“11”,s2.intern()则返回501。

System.out.println(s1==s2);
System.out.println(s1==s3);false
true

s1==s2 返回false是因为s1指向的是字符串常量池中的"11"对象(501),而s2指向的是堆中存储了"11"的地址的对象(601)
s1==s3 返回true 是因为s3和s1都指向的是字符串常量池中的"11"。

对String srt = new String(“str”)与 str1 = ”str“的区别不了解的话可以看篇文章

2、经典例题解释

例1

//1
String s = new String("1");
//2
s.intern();//调用此方法之前,字符串常量池中已经存在了"1".
//3
String s2 = "1";
//4
System.out.println(s==s2);
  • 执行1,会创建两个对像,在字符串常量池中创建一个”1“,在堆中创建一个String对象,并存储“1”在字符串常量池中的的地址。
  • 执行2,调用此方法之前,字符串常量池中已经存在了"1",所以此指令什么都没做,此时s指向堆中的对象。
  • 执行3,由于字符串常量池中已经存在了“1”,所以不需要再创建,返回“1”的地址,s2指向字符串常量池中的”1“。
  • 执行4,由于s指向堆中对象,s2指向字符串常量池中的对象,所以打印结果是false。

这是比较简单的例子
下面上强度了!!!!!!

例2

		//1String s3 = new String("1")+new String("1");//2s3.intern();//3String s4 = "11";//4System.out.println(s3==s4);
  • 执行1,会在堆中创建两个存储字符串”1“的地址的对象和一个字面量为”11“的String对象,在字符串常量池中创建一个”1“字符串实例。
    在编译期间,在创建String对象之前,会先创建一个StringBuilder对象,后面每次在堆中创建完一个String对象,会对该字符串执行LDC指令,LDC指令会先到字符串常量池中查找是否存在对应字符串实例的引用,如果有的话,那么直接返回这个字符串实例的地址给堆中的new的String对象,如果没有的话,会创建一个字符串实例,然后将其添加到字符串常量池中,之后再返回这个字符串实例对象的地址给堆中创建的对象。完成String对象初始化后,都会执行StringBuilder::append()方法,将该字符串拼接到StringBuilder对象里。当都拼接完,会执行StringBuilder::toString()方法,返回一个在堆中新new的String对象,value为"11"。
    可以通过编译后的字节码文件清晰的观察整个过程:
    在这里插入图片描述
    标注的都是刚才介绍的行为。

  • 执行2,由于toString()方法只在堆中创建了一个”存储11"的String对象,并没有在字符串常量池中创建"11"字符串实例。按之前的说法intern应该去字符串常量池中创建字符串”11“的实例,但是在JDK7中,并没有在字符串常量池中创建字符串"11"的实例,由于堆中已经存在了"11"这个String对象,那么为了节省空间,会在字符串常量池中申请一块空间,存放这个String对象的地址,并返回存放的地址,也就是堆中存储"11"的String对象的地址。

  • 执行3,会去字符串常量池中查找是否存在"11",因为第二行已经在字符串常量池中,创建了存储堆中存储"11"的String对象的地址的空间,则直接返回空间里面存储的堆中String对象的地址,所以s4也指向了堆中存储"11"的String对象。

  • 由于s3和s4都指向堆中同一个对象,所以打印结果为true。
    如图所示:
    在这里插入图片描述
    通过debug,可以看到两个句柄指向的地址是一样的:
    在这里插入图片描述
    打印结果:
    在这里插入图片描述

例3

		//1String s3 = new String("1")+new String("1");//2String s4 = "11";//3s3.intern();//4System.out.println(s3==s4);
  • 第一行执行结果与例2的第一行执行结果一致。
  • 执行2,由于字符串常量池中,还没有"11",则向字符串常量池中创建字符串"11"的实例,并返回实例的地址。
  • 执行3,由于字符串常量池中已经存在"11",则不需要再创建,返回实例的地址,但由于没有赋值操作,所以该行代码没有什么作用。
  • 此时,s3指向堆中存储了“11”的String对象,而s4指向的是字符串常量池中字符串为"11"的实例,所以指向的地址不同打印结果为false
    通过debug可以看到两个句柄指向的地址是不同的:
    在这里插入图片描述
    打印结果:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/73611.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式唯一ID实战

目录 一、UUID二、数据库方式1、数据库生成之简单方式2、数据库生成 - 多台机器和设置步长,解决性能问题3、Leaf-segment 方案实现4、双 buffer 优化5、Leaf高可用容灾 三、基于Redis实现分布式ID四、雪花算法1、雪花算法介绍2、 雪花算法生产环境架构:3…

【FAQ】调用视频汇聚平台EasyCVR的iframe地址,视频无法播放的原因排查

有用户反馈,在调用iframe地址后嵌入用户自己的前端页面,视频无法播放并且要求登录。 安防监控视频汇聚平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可提供视频监控直播、云端录像、视频云存储、视频集中…

【校招VIP】测试方案之测试用例分析

考点介绍 测试用例是测试岗面试和工作后的核心,在面试里对测试用例的分析是高频考查点。但是很多同学因为没有真实的商业产品需求,只能简单的看别人的用例学习,导致面试时被一个陌生问题卡住。 比如最简单的用户名密码输入,在商业…

元宇宙时代超高清视音频技术白皮书关于流媒体协议和媒体传输解读

流媒体协议 元宇宙业务场景对流媒体传输的实时性和互动性提出了更高的要求,这就需要在传统的 RTMP、SRT、 HLS 等基础上增加实时互动的支持。实时互动,指在远程条件下沟通、协作,可随时随地接入、实时地传递虚实融合的多维信息,身…

Blender增强现实3D模型制作指南【AR】

推荐:用 NSDT编辑器 快速搭建可编程3D场景 将静态和动画 3D 内容集成到移动增强现实 (AR) 体验中是增强用户沉浸感和参与度的高效方法。 然而,为 AR 创建 3D 对象可能相当艰巨,尤其是对于那些缺乏 3D 建模经验的人来说。 与添加视频或照片 AR…

python3 0基础学习----数据结构(基础+练习)

python 0基础学习笔记之数据结构 📚 几种常见数据结构列表 (List)1. 定义2. 实例:3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引,插入内容) 向指定…

从零实战SLAM-第八课(非特征点的视觉里程计)

在七月算法报的班,老师讲的蛮好。好记性不如烂笔头,关键内容还是记录一下吧,课程入口,感兴趣的同学可以学习一下。 --------------------------------------------------------------------------------------------------------…

听GPT 讲Prometheus源代码--util

Prometheus的util目录包含了一些通用的工具模块,主要包含以下文件: buckets.go 这个文件定义了一些常用的指标采样值范围(Quantile buckets),如:0.001,0.01,0.05,0.5,0.9,0.95,0.99,0.999等。这些buckets常用于计算指标的分位数线。 regex.go 这个文件定义了一些正则表达式匹配…

[保研/考研机试] 杨辉三角形 西北工业大学复试上机题 C++实现

题目描述 Time Limit: 1000 ms Memory Limit: 256 mb 输入n值,使用递归函数,求杨辉三角形中各个位置上的值。 输入描述: 一个大于等于2的整型数n 输出描述: 题目可能有多组不同的测试数据,对于每组输入数据, 按题目的要求输…

过来,我告诉你个秘密:送给程序员男友最好的礼物,快教你对象学习磁盘分区啦!小点声哈,别让其他人学会了!

[原文连接:来自给点知识](过来,我告诉你个秘密:送给程序员男友最好的礼物,快教你对象学习磁盘分区啦!小点声哈,别让其他人学会了!) 再唱不出那样的歌曲 听到都会红着脸躲避 虽然会经常忘了我依然爱着你 …

最新k8s集群搭建教程

本次安装在vmware虚拟机下开启3台2核2g的Ubuntu20.04系统 master:192.168.192.137 node1:192.168.192.136 node2:192.168.192.138 关闭防火墙 先查看防火墙状态,如果是关闭就不用管 ufw status关闭selinux,如果没有安…

【数理知识】三维空间旋转矩阵的欧拉角表示法,四元数表示法,两者之间的转换,Matlab 代码实现

序号内容1【数理知识】自由度 degree of freedom 及自由度的计算方法2【数理知识】刚体 rigid body 及刚体的运动3【数理知识】刚体基本运动,平动,转动4【数理知识】向量数乘,内积,外积,matlab代码实现5【数理知识】最…