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

news2024/11/24 2:45:16

文章目录

  • 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

		//1
		String s3 = new String("1")+new String("1");
		//2
        s3.intern();
        //3
        String s4 = "11";
        //4
        System.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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Redis缓存读写策略(三种)数据结构(5+3)

Redis缓存读写策略(三种) Cache Aside Pattern(旁路缓存模式) Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。 写: 先更新 db然后直接删除 cache 。 读 : …

爆肝整理,性能测试方法与关键指标以及瓶颈定位思路,一篇贯通...

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 性能测试方法 1、…

Mybatis 源码 ③ :SqlSession

一、前言 Mybatis 官网 以及 本系列文章地址: Mybatis 源码 ① :开篇Mybatis 源码 ② :流程分析Mybatis 源码 ③ :SqlSessionMybatis 源码 ④ :TypeHandlerMybatis 源码 ∞ :杂七杂八 在 Mybatis 源码 ②…

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia 初环境与设备环境准备克隆模型代码部署 ChatGLM-6B完整代码 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术&#x…

Go学习-Day1

Go学习-Day1 个人博客:CSDN博客 打卡。 Go语言的核心开发团队: Ken Thompson (C语言,B语言,Unix的发明者,牛人)Rob Pike(UTF-8发明人)Robert Griesemer(协助HotSpot编译器,Js引擎V8) Go语言有静态语言的…

Sentinel使用实例

不说了,直接上官方文档 https://github.com/alibaba/spring-cloud-alibaba/blob/master/spring-cloud-alibaba-examples/sentinel-example/sentinel-core-example/readme-zh.md Sentinel Example 项目说明 本项目演示如何使用 Sentinel starter 完成 Spring Clo…

推荐工具!使终端便于 DevOps 和 Kubernetes 使用

如果你熟悉 DevOps 和 Kubernetes 的使用,就会知道命令行界面(CLI)对于管理任务有多么重要。好在现在市面上有一些工具可以让终端在这些环境中更容易使用。在本文中,我们将探讨可以让工作流程简化的优秀工具,帮助你在 …

Intel汇编和ATT汇编的区别?

一、前缀不同 在 Intel 语法中,没有寄存器前缀或立即前缀。 然而,在 AT&T 中,寄存器的前缀是“%”,而 immed 的前缀是“$”。 Intel 语法十六进制或二进制即时数据分别带有“h”和“b”后缀。 此外,如果第一个十六…

最新AI系统ChatGPT网站程序源码+搭建教程/公众号/H5端/安装配置教程/完整知识库

1、前言 SparkAi系统是基于国外很火的ChatGPT进行开发的Ai智能问答系统。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。 那么如何搭建部署AI创作ChatGPT?小编这里写一个详细图文教程吧!…

nginx一般轮询、加权轮询、ip_hash等负载均衡模式配置介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备: 2.190均衡服务器,2.191web服务器1,2.160web服务器2,三台设备均安装nginx,两台web服务器均有网页内容 1.一般轮询负载均衡 (1&#xff09…

基于深度信念神经网络的矿石产量预测,基于DBN的矿石产量预测,DBN的详细原理

目录 背影 DBN神经网络的原理 DBN神经网络的定义 受限玻尔兹曼机(RBM) DBN的矿石产量预测 基本结构 主要参数 数据 MATALB代码 结果图 展望 背影 DBN是一种深度学习神经网络,拥有提取特征,非监督学习的能力,是一种非常好的分类算法,本文将DBN算法进行矿石产量预测 DB…

golang Cobra 快速使用

package mainimport("fmt""os""github.com/spf13/cobra" )func f1(){fmt.Printf("这是主命令的运行函数 ") } func f2(){fmt.Println("这是一个子命令的运行函数") }func main(){var rootCmd &cobra.Command{Use: &quo…

【果树农药喷洒机器人】Part8:果树对靶变量喷药实验

📢:博客主页 【https://blog.csdn.net/weixin_51244852】 📢:文章若有幸对你有帮助,可点赞 👍 收藏 ⭐不迷路🙉 📢:内容若有错误,敬请留言 📝指正…

Maven - 全面解析 Maven BOM (Bill of Materials):打造高效依赖管理与模块化开发

文章目录 Whats BOMWhy Bom常見的官方BOMSpring Maven BOM dependencySpringBoot SpringCloud Maven BOM dependencyJBOSS Maven BOM dependencyRESTEasy Maven BOM dependencyJersey Maven BOM dependency How Bom定义BOM其他工程使用的方法 BOM VS POM What’s BOM BOM&…

jmeter中用户参数和用户定义的变量的区别

如果使用jmeter做过参数化的人都知道,参数化的方式有多种,其中一种就是使用用户定义的变量,还有一种是使用用户参数。那么,这两个有什么异同呢? 一、先说相同的点: 1、都可以参数化,以供sample…

ArrayList浅拷贝clone,Kotlin

ArrayList浅拷贝clone&#xff0c;Kotlin import kotlin.collections.ArrayListfun main() {var list ArrayList<MyData>()for (i in 0..<3) {list.add(MyData(i, 0))}//浅拷贝list到copyListvar copyList list.clone()println(list)println(copyList)println("…

SSM整合(XML方式)

文章目录 SSM整合之后xml方式1 系统环境1.1 软件环境1.2 项目环境1.3 配置web.xml1.4 配置jdbc.properties文件1.5 配置SpringMVC核心文件1.6 配置Spring的核心文件1.7 配置MyBatis的核心文件1.8 配置数据库1.9 配置文件位置 2 编写后端代码2.1 编写实体类2.2 编写Dao接口2.3 编…

AOP与SpringAOP

AOP与SpringAOP 一、什么是AOP&#xff0c;什么是SpringAOP二、AOP与拦截器的区别三、实现SpringAOP1.添加SpringBootAOP依赖2.创建切面3.创建切点4.创建通知5.创建连接点 效果 一、什么是AOP&#xff0c;什么是SpringAOP AOP即Aspect-Oriented Programming面向切面编程。 它是…

CRC 校验码

CRC 校验码 题目解答发送端如何计算商 接收端 题目 假设生成多项式为 G(X)X4X31&#xff0c;要求出二进制序列10110011的CRC校验码 解答 发送端 首先 生成多项式为&#xff1a;G(X)X4X31&#xff0c;改写为二进制比特串为11001(有X的几次方&#xff0c;对应的2的几次方的位…

stable diffusion 单张图片换头roop安装配置

1.首先安装秋叶大佬的webui 2.然后在拓展里面搜索roop,下载roop插件,然后重启webui 3.重启后,在文生图和图生图的界面,就可以看到roop的入口 4.这里面,需要提前安装Visual Studio. 勾选一些必要的选项,这里可以参照b站的视频 # 秋叶版本Stablediffusion的Roop插件的安装 …