1 String中intern的方法

jdk1.8 Jmap pid info- 37103 interned Strings occupying 4038832 bytes ,String intern()方法 Heap Configuration: //堆内存初始化配置 MinHeapFreeRatio = 40 //堆最小空闲比率 MaxHeapFreeRatio = 70 //堆最大空闲比率 MaxHeapSize = 2147483648 (2048.0MB) //堆最大空间 NewSize ... 阅读详情
 

首先查看官方API那个的解释:

——————————————————————————————————

intern

public String intern()

返回字符串对象的规范化表示形式。

一个初始时为空的字符串池,它由类 String 私有地维护。

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

所有字面值字符串和字符串赋值常量表达式都是内部的。

返回:

一个字符串,内容与此字符串相同,但它保证来自字符串池中。

——————————————————————————————————

尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作。在调用”ab”.intern()方法的时候会返回”ab”,但是这个方法会首先检查字符串池中是否有”ab”这个字符串,如果存在则返回这个字符串的引用,否则就将这个字符串添加到字符串池中,然会返回这个字符串的引用。

可以看下面一个范例:

 1 String str1 = "a";
 2 String str2 = "b";
 3 String str3 = "ab";
 4 String str4 = str1 + str2;
 5 String str5 = new String("ab");
 6  
 7 System.out.println(str5.equals(str3));
 8 System.out.println(str5 == str3);
 9 System.out.println(str5.intern() == str3);
10 System.out.println(str5.intern() == str4);

得到的结果:

true

false

true

false

 

为什么会得到这样的一个结果呢?我们一步一步的分析。

第一、str5.equals(str3)这个结果为true,不用太多的解释,因为字符串的值的内容相同。

第二、str5 == str3对比的是引用的地址是否相同,由于str5采用new String方式定义的,所以地址引用一定不相等。所以结果为false。

第三、当str5调用intern的时候,会检查字符串池中是否含有该字符串。由于之前定义的str3已经进入字符串池中,所以会得到相同的引用。

第四,当str4 = str1 + str2后,str4的值也为”ab”,但是为什么这个结果会是false呢?先看下面代码:

 1 String a = new String("ab");
 2 String b = new String("ab");
 3 String c = "ab";
 4 String d = "a" + "b";
 5 String e = "b";
 6 String f = "a" + e;
 7
 8 System.out.println(b.intern() == a);
 9 System.out.println(b.intern() == c);
10 System.out.println(b.intern() == d);
11 System.out.println(b.intern() == f);
12 System.out.println(b.intern() == a.intern());

运行结果:

false

true

true

false

true

由运行结果可以看出来,b.intern() == a和b.intern() == c可知,采用new 创建的字符串对象不进入字符串池,并且通过b.intern() == d和b.intern() == f可知,字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量(如f中的e)则不会进入字符串池中。但是字符串一旦进入字符串池中,就会先查找池中有无此对象。如果有此对象,则让对象引用指向此对象。如果无此对象,则先创建此对象,再让对象引用指向此对象。

    当研究到这个地方的时候,突然想起来经常遇到的一个比较经典的Java问题,就是对比equal和==的区别,当时记得老师只是说“==”判断的是“地址”,但是并没说清楚什么时候会有地址相等的情况。现在看来,在定义变量的时候赋值,如果赋值的是静态的字符串,就会执行进入字符串池的操作,如果池中含有该字符串,则返回引用。

执行下面的代码:

 1 String a = "abc";
 2 String b = "abc";
 3 String c = "a" + "b" + "c";
 4 String d = "a" + "bc";
 5 String e = "ab" + "c";
 6         
 7 System.out.println(a == b);
 8 System.out.println(a == c);
 9 System.out.println(a == d);
10 System.out.println(a == e);
11 System.out.println(c == d);
12 System.out.println(c == e);

运行的结果:

true

true

true

true

true

true

运行的结果刚好验证了我刚才的猜想
从芯片选型到光学集成:手持激光测距仪硬件设计全解析 本文全面解析手持激光测距仪的硬件设计,从芯片选型到光学集成,详细介绍了相位法测距技术的核心原理与方案选择。通过模块化设计、信号链路优化及PCB布局技巧,实现毫米级精度。文章还分享了量产化关键控制点,帮助工程师规避常见设计陷阱,提升产品可靠性。 阅读详情

相关推荐

Lmbench测试集 --- 延迟测试工具lat_mem_rd

lmbench测试集简介 以及 lat_mem_rd延迟测试工具: 如何测试、测试结果、源码分析

MonologueYY的博客 1万+

jdk1.8之后的String.intern()方法内存分析

关于String.intern()方法,这个问题都被问烂了,有的文章在分析的时候还在用jdk1.7,jdk1.8之后内存模型发生了变化,内存的变化也会影响intern方法的执行,这里有必要写文章分析一下,请大家务必从头开始看,这样才能搞懂 1.字符串常量池划分 jvm对字符串常量池在不同jkd版本有不同的划分,这里用hotspot来分析,文章后部分会使用,主要有以下三种方式 大致划分为这几个部分...

Alphr的博客 2291

DSP28377内存不够用?手把手教你合并RAM/FLASH块,解决CCS20链接器报错

本文详细介绍了在CCS20开发环境中解决DSP28377内存不足问题的方法,通过合并RAM/FLASH块优化CMD文件配置,有效解决链接器报错。文章包含内存布局对比、改写步骤、FreeRTOS集成注意事项及调试技巧,帮助开发者提升内存利用率与项目性能。

weixin_42524762的博客 143

jdk1.8中String的intern方法简单介绍

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34297300的博客 658

LoRa正点原子模块组网步骤

按照我上一篇的博客和视频演示,相信大家一定都可实现了lora模块点对点的通信了。那我们来进行一个比较有高难度的设计吧! 使用多个loRa模块去完成一个组网设计: 在这之前一定要配置模块信息为定点传输 AT+TMODDE要等于1奥 第一步分析通讯协议: 点对点通讯是在透明传输的条件下,地址和信道都是一样的,直接发送接受数据。 组网呢我们利用是: 定向传输就是 A、B的地址、信道不同 假如A是要想B发送信息就用函数来下面: int b[5]...

weixin_43205178的博客 4082

HHD Device Monitoring Studio:破解版在串口调试中的实战应用

本文详细介绍了HHD Device Monitoring Studio破解版在串口调试中的实战应用,包括安装指南、串口监控功能解析、Modbus RTU协议分析案例以及自定义协议解析技巧。通过具体操作步骤和性能优化建议,帮助开发者高效完成端口监控和调试任务,提升工作效率。

weixin_29268331的博客 943

基于JDK1.6和JDK1.7对String.intern()方法的理解

最近看了深入理解Java虚拟机,对String.intern()方法虚拟机的实现很是不理解,经过查找网上的各类文章,现在总结一部分。 在理解String.intern()方法之前,我觉得首先应该了解一下通过创建对象的方式和直接创建字符串的方式对象生成机制便于理解一下代码。 String str1 = new String("1");//--创建对象的方式 这种创建方式,是在堆中创建一个字符串...

qq_35850405的博客 323

从零构建XVC协议栈:FPGA+W5300的跨界调试架构实战

本文详细介绍了如何从零构建XVC协议栈,通过FPGA与W5300以太网控制器的创新组合实现跨界调试架构。重点解析了JTAG时序逆向、TCP/IP协议栈集成与XVC协议实现,提供了硬件设计优化和性能加速技术,为嵌入式开发者和FPGA工程师提供实用的远程调试解决方案。

raspberrypi5的博客 247

String和它的常量池朋友以及intern()方法在JDK1.7中的变化

此文摘自:https://langinteger.github.io/2018/04/19/java-String-pool/ Java语言中有8种基本数据类型和一种比较特殊的数据类型String。为了使用起来更加高效(时间上和空间上),JVM为这些类型的数据分别维护了系统级别的常量池。本文主要叙述String类型的常量池以及向常量池中添加对象的intern()方法在JDK1.7以后版本中的变化。...

shy_black的博客 402

H3C-V7防火墙配置SSL VPN IP资源典型案例(华三)

H3C-V7防火墙配置SSL VPN IP资源典型案例(华三)

m0_68265458的博客 5168

【深度学习】脸部修复,CodeFormer,论文,实战

Blind face restoration是一个高度 ill-posed 的问题,通常需要辅助引导来 1) 改善从降级输入到期望输出的映射,或者 2) 补充在输入中丢失的高质量细节。在本文中,我们展示了在一个小的代理空间中学到的离散码本先验可以通过将盲目的面部恢复建模为 a code prediction task来大大减少恢复映射的不确定性和模糊性,同时为生成高质量面部提供丰富的视觉元素。

q742971636的博客 2994

JDK1.6和JDK1.7关于String.intern()方法差异详解

JDK1.6和JDK1.7关于String.intern()方法差异详解 最近看《深入理解Java虚拟机》时,在2.4.3 方法区和运行时常量池溢出这一章节看到了String.intern(),当时还没太明白,网上查一些资料,之后再仔细揣摩书本时才算是有了一些自己的理解,深知笔记对于理解知识的重要性,于是写下这篇博客,也算是自己成长路上的一个记录。 前置知识 因为使用的是《深入理解Java虚拟机》书中的例子,里面涉及对象创建,因此准备先理清Java创建字符串对象的过程。 public class Hello

yangxiao的博客 555

【如何学习CAN总线测试】——AUTOSAR网络管理自动化测试(CAPL源码)

上一章介绍的是AUTOSAR网络管理如何测试、用例设计,对于不满足手工测试的同学,本章就介绍AUTOSAR网络管理自动化测试。

测试领域技术分享 6239

String.intern() 方法__jdk1.6与jdk1.7的不同

0.引言 什么都先不说,先看下面这个引入的例子: [java] view plain copy String str1 = new String("SEU")+ new String("Calvin");       System.out.println(str1.intern() == str1);    System.out.println

Not_AC的博客 1572

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

String的intern方法在jdk1.6与jdk1.7之间的区别

最近看到这种类型的面试题,十分不解,就对此做了一些研究,现记录一下学习成果,待自己以后回顾查阅: 首选确定一下intern方法的功能 /** * Returns a canonical representation for the string object. * <p> * A pool of strings, initially empty, is maintai...

YesNoBut的博客 1920

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

String.intern() 方法__jdk1.6与jdk1.7/jdk1.8的不同

1、为什么要使用intern()方法 intern方法设计的初衷是为了重用string对象,节省内存 用代码实例验证下 public class StringInternTest { static final int MAX = 100000; static final String[] arr = new String[MAX]; pu...

weixin_30375247的博客 268

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化

字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 public class RuntimeConstantPoolOOM { public static void main(String[] args) throws Exceptio...

weixin_30363817的博客 230

Java技术——你真的了解String类的intern()方法吗(jdk1.6和1.7之后不一样!!)(String类的intern看这一篇就足够了)

0.引言什么都先不说,先看下面这个引入的例子:[java] view plain copyString str1 = new String("SEU")+ new String("Calvin");      System.out.println(str1.intern() == str1);   System.out.println(str1 == "SEUCalvin");  本人JDK版本1...

HD243608836的博客 497

JDK1.8中字符串常量池的优化之String的intern()

JDK每次升级都会做很多优化,我们使用最多的String常量类也在不断被优化。这次和大家分享的是String优化手段之一的intern()方法。 源码API如下: /** * Returns a canonical representation for the string object. * * A pool of strings, initially empty, is maintained privately by the * class {@code String}. * * When th

WLQ0621的博客 2039

JAVA中String.intern方法(JDK1.7及以上版本)

intern源码如下: /** * Returns a canonical representation for the string object. * <p> * A pool of strings, initially empty, is maintained privately by the * class {@code String}....

hzh_shine的博客 555

JDK1.8中String类的intern()方法学习

jdk1.8字符串常量池是位于堆中; 在jdk1.8中使用如下指令时会同时在堆中和常量池(前提是常量池中还没有该对象)中创建字符串对象,但是s是指向堆中。 String s = new String("HELLO"); 如下方法会判断常量池中是否存在s,若存在无须其它操作,s的指向不会发生更改;若不存在(但堆中存在s指向的对象),则在常量池中建立指向堆中对象的引用; s.intern(...

MonkeyDpengpeng的博客 566

String中intern()方法

本文参考 https://blog.youkuaiyun.com/believesoul/article/details/79588305 ,我对这篇文章进行了一些小小的整理和修改。这篇文章很好的对intern()方法进行了阐述。 最近在看字符串相关知识的时候,又看到了关于字符串创建方式和是否相等的相关问题,回忆起之前碰到的一个String中的intern()方法,它是一个本地方法(由Java语言外的语言编写...

BestQiang的博客 1万+

Java技术——你真的了解String类的intern()方法吗(1)

下面是辛苦给大家整理的学习路线,有需要的可以点击这里免费获取“1”) +newString(“1”);“11”;输出结果为:JDK1.6以及以下:falsefalseJDK1.7以及以上:falsetrue自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

2401_83621499的博客 889

java 1.7 常量池_字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化

字符串常量池也是运行时常量池jdk1.6中,它是在方法区中,属于“永久代”jdk1.7中,它被移除方法区,放在java堆中jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了public classRuntimeConstantPoolOOM {public static void main(String[] args) throwsException{String str1= new...

weixin_33796891的博客 328

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 290
上一篇: 如何自定义Struts2表单验证后的错误信息显示格式/样式
下一篇: hibernate id 生成器
风吹Mai浪
博客等级 码龄18年 4粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值