JVM的知识这里总结的很详细:https://github.com/doocs/jvm/blob/master/README.md,因此在本博客也不会再对其中的东西重复总结了。

intern的作用

简单的讲,intern方法是把调用者丢到常量池里,并返回一个引用。

String s = new String("sq") + new String("666");      //line1
String s1 = s.intern(); //line2

以上代码line1在堆里创建两个字符串,并且拼接到一起。line2 是将这个凭借好的字符串放到常量池中,并返回一个指向常量池中的这个字符串的引用,在例子中赋给了s1。

为什么需要intern“多此一举”?因为是处理运行时生成的字符串

在上一篇讲常量池和JVM内存结构中说:初次创建字符串会自动在常量池中创建一个字符串。也就是说:new一个字符串时,会生产两个字符串,堆中一个,字符串常量池中创建一个,一共两个。那么,为什么还要调用intern() 方法呢?它起作用了吗?

我的理解是:new字符串时自动在字符串常量池也创建一个字符串(字符串常量池还不存在相同的字符串)仅限编译时的情况,而intern则是将程序运行时生成的字符串的引用丢一份进字符串常量池。

        像以上的情况,两个new运算符只是自动在池中创建了 “sq”   "666" 两个字符串,而没有 “sq666” ----因为这是在程序跑起来才通过“+”生成的。当程序跑到 line2 这里,就通过intern把  “sq666” 的引用也丢进池子。

不信?看如下例子:

片段1:
String s = new String("sq") + new String("666");
s.intern();
tring s2 = "sq666";
System.out.println(s == s2) //结果为true 片段2:
String s = new String("sq") + new String("666");
String s2 = "sq666";
System.out.println(s == s2) //结果为false

片段2 仅仅只比片段1少了 intern方法的调用,结果却相反。因为通过字面量创建字符串(即 String = "sq666")的方式只会生成一个字符串,放在池中,且如果池中已有这个字面量的字符串,则直接把引用指向这个已有的字符串即可,而不需重复创建。

综上,在程序跑起来时生成了 "sq666" 字符串,片段2没有把它丢进池子,所以通过字面量创建时又在池子中创建了一个新的,二者的地址自然也不相等了。片段1却是先把运行时生成的 "sq666" 的引用丢进了池子,这样通过字面量创建时发现池子中有现成的,不需要创建新的。因此二者地址自然也相等啦。

intern 随常量池的变化---只丢引用了

上一篇说到:随着元空间取代永久代,字符串常量池也不再存在于永久代,也不存在于元空间,而是存在于堆中。intern方法也有一些改变,以前intern方法是把这个字符串丢一份拷贝进字符串常量池,在这之后intern方法只是把字符串的引用丢一份进了字符串常量池。(也有不同意见:说还是丢的字符串内容,而非引用)

我认为丢的是一份引用,因为对于上述代码片段1返回的是true。我们假设: 运行时生成的字符串"sq666",地址为 ’oxa‘ ,如果调用intern是丢了一份拷贝版的字符串到池中,那么被丢进池的拷贝版字符串地址就肯定不是‘oxa’了(假设为’oxb‘),最后执行:String s2 = "sq666"; s2的内容就是`oxb‘,片段1应该返回的就是false了。

一些注意点:

String s = "sq"+"666";      经过优化是只在池中生成一个字符串的,即"sq666"

运行时生成字符串的情况还有: 调用StringBuilder的append方法等等

String类的intern()方法,随常量池发生的变化的更多相关文章

  1. JVM体系结构之七:持久代、元空间(Metaspace) 常量池==了解String类的intern()方法、常量池介绍、常量池从Perm-->Heap

    一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String inter ...

  2. String类中intern方法的原理分析

    一,前言 ​ 昨天简单整理了JVM内存分配和String类常用方法,遇到了String中的intern()方法.本来想一并总结起来,但是intern方法还涉及到JDK版本的问题,内容也相对较多,所以今 ...

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

    0.引言 什么都先不说,先看下面这个引入的例子:   String str1 = new String("SEU")+ new String("Calvin") ...

  4. String类的intern()方法

    0.引言 什么都先不说,先看下面这个引入的例子: String str1 = new String("SEU")+ new String("Calvin"); ...

  5. Java String类的intern()方法

    该方法的作用是把字符串加载到常量池中(jdk1.6常量池位于方法区,jdk1.7以后常量池位于堆) 在jdk1.6中,该方法把字符串的值复制到常量区,然后返回常量区里这个字符串的值: 在jdk1.7里 ...

  6. JAVA中String类的intern()方法的作用

    一般我们变成很少使用到 intern这个方法,今天我就来解释一下这个方法是干什么的,做什么用的 首先请大家看一个例子: public static void main(String[] args) t ...

  7. String中的intern方法

    上一篇你真的会用String吗(3)-关于字符串拼接中我们提到了String.intern()方法,本篇我们就来详细的看下这个方法是干嘛的.首先来看下jdk8中这个方法的注释: When the in ...

  8. java.lang.String 类的所有方法

    java.lang.String 类的所有方法 方法摘要 char charAt(int index) 返回指定索引处的 char 值. int codePointAt(int index) 返回指定 ...

  9. 关于JAVA的String类的一些方法

    一.得到字符串对象的有关信息 1.通过调用length()方法得到String的长度. String str=”This is a String”; int len =str.length(); 2. ...

随机推荐

  1. java - java集合类

    1.接口实现类 ①List List list1 = new ArrayList(); List list2 = new LinkedList(); ②Set Set<String> se ...

  2. 神奇的 SQL 之 CASE表达式,妙用多多 !

    前言 历史考试选择题:黄花岗起义第一枪谁开的? A宋教仁 B孙中山 C黄兴 D徐锡麟,考生选C. 又看第二题:黄花岗起义第二枪谁开的? 考生傻了,就选了个B. 接着看第三题:黄花岗起义中,第三枪谁开的 ...

  3. Divide and Conquer

    1 2 218 The Skyline Problem     最大堆   遍历节点 public List<int[]> getSkyline(int[][] buildings) { ...

  4. 【Python3爬虫】当爬虫碰到表单提交,有点意思

    一.写在前面 我写爬虫已经写了一段时间了,对于那些使用GET请求或者POST请求的网页,爬取的时候都还算得心应手.不过最近遇到了一个有趣的网站,虽然爬取的难度不大,不过因为表单提交的存在,所以一开始还 ...

  5. .NET加水印/验证码的NuGet包

    .NET加水印/验证码的NuGet包 我的在前两篇文章(水印,验证码)中,我介绍了使用Direct2D给图片加水印/验证码,今天我将其进行了封装,发布了一个NuGet包Sdcb.Imaging: &l ...

  6. 使用f12定位bug

    为什么找到网站中的bug后还要去分析它到底是属于前端bug还是后端bug 三个原因: 1.在一些公司,一个系统可能是由前端团队和后端团队共同开发出来的,因此在分配bug的时候,不同模块的bug一般都会 ...

  7. cmd与monkey测试

    monkey测试的相关命令 monkey是模拟用户触摸操作,不支持条件判断.monkey命令格式:  启动安卓模拟器/真机 点击运行->输入cmd->进入命令行界面 查看设备连接情况,ad ...

  8. 【Java例题】5.5 映射类的使用

    5.映射类的使用.使用HashMap保存英文-中文对照单词词典.单词词典可以增加和删除词汇.输入一个英文单词,翻译成中文并显示.输入一个中文单词,翻译成英文并显示. package chapter6; ...

  9. 阿里P8Java大牛仅用46张图让你弄懂JVM的体系结构与GC调优。

    本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.图文并茂不生枯燥. 此PPT长达46页,全部展示篇幅过长,本文优先分享前十六页 ...

  10. IOS7.0唯一“设备ID”的获取方法

    ios7.0 以后通过sysctl获得的mac地址已经失效,所有设备均为020000000000. 可以通过苹果的keychain机制,实现设备的唯一ID标示. 具体过程:在app第一次安装时,生成一 ...