String#intern

news2025/1/12 1:08:57

1.intern方法

intern()方法可以在运行期间向字符串中动态加入字符串实例的方式,它的功能很简单,总结起来就一句话
可以在运行时向字符串池中添加字符串常量
添加的原则是,如果常量池中存在当前字符串,则直接返回常量池中它的引用;如果常量池中没有此字符串,则将此字符串的引用放入常量池,然后返回这个引用。
字符串进入常量池有两个途径:
1.字面量在编译器会进入Class的常量池,在类加载后会进入运行时常量池
2.使用intern()

String#intern()方法在JVM中是通过JNI调用C++实现的,其实里面调用的C++当中的StringTable的intern()方法,它的内部结构和HashMap类似,但是它不能扩容,默认大小是1009
如果字符串常量池的String非常躲,就会造成Hash冲突,从而导致链表会很长,它的查询性能将会从O(1)变成O(n),当调用intern方法时性能将会下降
在JDK6的版本中大小是固定的,在JDK7中可以通过参数来设置-XX:StringTableSize=12345

public static void main(String[] args) {
    String s = new String("1");
    s.intern();
    String s2 = "1";
    System.out.println(s == s2);

    String s3 = new String("1") + new String("1");
    s3.intern();
    String s4 = "11";
    System.out.println(s3 == s4);
}

s == s2 // false
s和s2比较分析:
String s = new String("1");
new String(“1”)同时创建了两个对象
一个对象是常量池中的"1"
一个是堆中的String对象
由于是new出来了的对象,s指向的是堆中的引用
s.intern();
调用intern方法,如果常量池中存在该字符串,则返回常量池引用,
如果不存在则将此字符串的引用加入到常量池中,然后返回
此时 常量池中已经有"1"这个字符串了,不需要再向常量池中添加,
所以这个地方返回的是常量池中的引用,另外返回的这个常量池的引用也并没有赋值给其他变量
String s2 = "1";
s2创建了一个"1"的字符串对象,这个时候会向StringTable(常量池)中查询是否存在该字符串,如果存在则返回这个引用,注意这个引用是常量池中的引用
System.out.println(s == s2);
s指向堆中的引用
s2指向的是常量池中的引用
在JDK6中,字符串常量池是放在Perm区域的,也就是放在方法区当中
方法区中的引用和堆中的引用,两者是属于不同的区域,必然是不相等的false

在JDK7中,字符串常量池移动到了堆中,原因是方法区的容量相比堆空间比较小,存储不了太多的常量,不过并不影响结果,仍然是两个区域内的对象进行比较仍然是false

s3和s4比较分析:
String s3 = new String("1") + new String("1");
s3在这里创建了两个对象,一个是堆中的"1"字符串对象,另一个两个new String(“1”) 拼接起来的"11"字符串对象放入到了堆中,但常量池中是没有这个"11"的
s3指向的是堆中的"11"对象
s3.intern();
接着s3调用intern方法,将"11"字符串对象放入到了字符串常量池中
在JDK6和JDK7的版本处理是不同的
在JDK6中,是复制堆中的字符串对象添加到字符串常量池中
在JDK7中,是复制堆中的字符串对象的引用添加到字符串常量池中
String s4 = "11";
s4在创建"11"字符串对象时,会先在StringTable中查询一番,如果有则返回常量池中的引用,如果没有则添加进去
在前面s3.intern()步骤中,由于已经将"11"放入到了字符串常量池中,所以这里返回的是常量池中的引用
System.out.println(s3 == s4);
由于intern()方法在不同的JDK版本里面会有差异,所以它们的比较结果也是不同的
在JDK6中,s4指向的是常量池中引用(堆对象的副本),由于内存区域不一样,所以为false
在JDK7中,s4指向的是常量池中引用(堆对象的引用),s4虽然指向的也是常量池中的引用,但是常量池中存储的这个引用是堆对象的引用,所以两者在比较时是一样的,所以为true
在这里插入图片描述
在这里插入图片描述

下面还有一段代码,各位可以再思考下,结果是怎样的

public static void main(String[] args) {
    String s = new String("1");
    String s2 = "1";
    s.intern();
    System.out.println(s == s2);

    String s3 = new String("1") + new String("1");
    String s4 = "11";
    s3.intern();
    System.out.println(s3 == s4);
}

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

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

相关文章

【博士每天一篇论文-实验分析】Toroidal topology of population activity in grid cells

阅读时间:2023-11-18 1 介绍 年份:2022 作者:Richard J. Gardner,挪威科技大学卡维利系统神经科学研究所和神经计算中心,挪威特隆赫姆 期刊: Nature 引用量:194 这篇论文通过揭示格状细胞网络…

Django的数据库模型的CharField字段的max_length参数与中文字符数的关系探索(参数max_length的单位是字符个数还是字节数?)

01-清理干净之前的数据库迁移信息 02-根据setting.py中的信息删除掉之前建立的数据库 03-删除之后重新创建数据库 04-models.py中创建数据库模型 from django.db import modelsclass User(models.Model):username models.CharField(max_length4)email models.EmailField(uni…

训练自己的GPT2

训练自己的GPT2 1.预训练与微调2.准备工作2.在自己的数据上进行微调 1.预训练与微调 所谓的预训练,就是在海量的通用数据上训练大模型。比如,我把全世界所有的网页上的文本内容都整理出来,把全人类所有的书籍、论文都整理出来,然…

C++标准学习--tuple

以下帖子介绍的比较详细: C的 tuple_c tuple-CSDN博客 tuple 是 C11 新标准里的类型,它是一个类似 pair 类型的模板。tuple 是一个固定大小的不同类型值的集合,是泛化的 std::pair。我们也可以把它当做一个通用的结构体来用,不需…

Golang,Gin框架使用ShouldBindJSON时出现EOF报错

前言 做毕设ing,使用的是Gin框架做的一个简单的管理系统。但偶尔也会碰到一些稀奇古怪的Bug,因此记录一下。 问题描述 api是这样写的 func UserRegisterHandler(c *gin.Context, user *usecase.UserOperate) {if err : c.ShouldBindJSON(&UserReg…

满足ITOM需求的网络监控工具

IT 运营管理(ITOM)可以定义为监督 IT 基础架构的各种物理和虚拟组件的过程;确保其性能、运行状况和可用性;并使它们能够与基础架构的其他组件无缝协作。IT 运营管理(ITOM)在大型 IT 管理模型中也发挥着积极作用,包括 I…

Arthas CPU 火焰图技术 简谈

1.基础命令 help 作用 查看命令帮助信息,可以查看当前 arthas 版本支持的指令,或者查看具体指令的使用说明。cat 作用 打印文件内容,和linux里的cat命令类似,如果没有写路径,则展示当前目录下的文件 使用参考 cat /t…

AIGC视频生成:Pika1.0快速入门详解

Pika1.0快速入门详解 一、简介二、登录三、参数设置1、改变画面大小(Aspect ratio)2、改变帧数大小(Frames per second)3、镜头平移(Camera control)4、画面运动控制(Strength of motion&#x…

Java异常及网络编程

异常续 throws关键字 当一个方法中使用throw抛出一个非RuntimeException的异常时,就要在该方法上使用throws声明这个异常的抛出。此时调用该方法的代码就必须处理这个异常,否则编译不通过。 package exception; ​ /*** 测试异常的抛出*/ public clas…

计算机体系结构----重排序缓冲(ROB)

ROB的思想:不按顺序完成指令,但在使结果对体系结构状态可见之前重新排序 当指令被解码时,它会在 ROB 中保留下一个顺序条目当指令完成时,它将结果写入 ROB 条目当指令在 ROB 中最早并且无一例外地完成时,其结果移动到…

多维时序 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量时间序列预测

多维时序 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量时间序列预测 目录 多维时序 | Matlab实现RIME-HKELM霜冰算法优化混合核极限学习机多变量时间序列预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现RIME-HKELM霜冰算法优化混合核极限学…

【论文综述】一篇关于GAN在计算机视觉邻域的综述

前言 这是一篇关于GAN在计算机视觉领域的综述。 正文 生成对抗网络是一种基于博弈论的生成模型,其中神经网络用于模拟数据分布。应用领域:语言生成、图像生成、图像到图像翻译、图像生成文本描述、视频生成。GAN模型能够复制数据分布并生成合成数据&a…

“编程语言大比拼:Python、JavaScript、Java与C#的优劣与选择“。

以下是一篇关于不同编程语言特性的比较和选择的文章。 在当今的编程世界中,有许多种不同的编程语言可供选择。每种语言都有其独特的特性和优点,这使得选择最适合特定项目的语言变得复杂。本文将比较几种流行的编程语言,以帮助您了解它们的特…

详细讲解MybatisPlus实现逻辑删除

目录 前言1. 基本知识2. 实战Demo3. 拓展 前言 对于MybatisPlus的相关知识可在我的博客进行搜索 对应的CRUD相关知识也可看我这篇文章:【Java项目】实战CRUD的功能整理(持续更新) 在讲述逻辑删除这个概念时,先引入另外一个概念&…

如何快速断行、分割行、切割行、换行、限制每行字数、平均分割每行字数、序号自动换行、关键字断行等等内容格式整理

首先,需要用到的这个工具: 百度 密码:qwu2蓝奏云 密码:2r1z 打开工具,切换到“文章工作域”(嗯...默认就是) 找到这个,多内容断行分割 点击打开,出现如下窗口设置 相关的…

国产服务器 BIOS下组建RADI不同RAID卡-超详细

国产服务器 长城 组建Raid的方法 说明 大多数国产服务器通用型服务器进入BIOS的都是按DEL键。 9361RAID卡组建方法 在服务器启动过程中,按下DEL键进入BIOS界面。 进入设备管理器,选择AVAGO MegaRAID页签。 3. 进入RAID卡设备,选择Main Me…

软件测试|MySQL CROSS JOIN:交叉连接的详细解析

简介 在 MySQL 数据库中,CROSS JOIN 是一种用于生成两个或多个表的笛卡尔积的连接方法。CROSS JOIN 不需要任何连接条件,它将左表的每一行与右表的每一行进行组合,从而生成一个包含所有可能组合的结果集。本文将详细介绍 MySQL 中的 CROSS J…

Ubuntu 22.04.3 LTS arm64 aarch64 ISO jammy-desktop-arm64.iso 下载

Ubuntu 22.04.3 LTS (Jammy Jellyfish) Daily Build 参考 Are there official Ubuntu ARM / aarch64 desktop images? - Ask Ubuntu

Web组件的使用

文章目录 1 概述2 加载网页加载在线网页加载本地网页 3 网页缩放文本缩放 4 Web组件事件Web组件处理JS confirm事件 5 Web和JavaScript交互启用JavaScriptWeb组件调用JS方法JS调用Web组件方法 6 处理页面导航7 调试网络应用8 参考链接 1 概述 相信大家都遇到过这样的场景&…

强化学习求解TSP(六):Qlearning求解旅行商问题TSP(提供Python代码)

一、Qlearning简介 Q-learning是一种强化学习算法,用于解决基于奖励的决策问题。它是一种无模型的学习方法,通过与环境的交互来学习最优策略。Q-learning的核心思想是通过学习一个Q值函数来指导决策,该函数表示在给定状态下采取某个动作所获…