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. JasperReport报表

    最近在做报表工作,公司要求使用正版免费的报表软件,想想还是用JasperReport. JasperReport是一个纯Java写的开源免费报表工具库,在java开源免费报表中,排在前列. 可是开源免 ...

  2. springBoot-mongodb

    作者:纯洁的微笑出处:http://www.ityouknow.com/ 版权归作者所有,转载请注明出处 mongodb是最早热门非关系数据库的之一,使用也比较普遍,一般会用做离线数据分析来使用,放到 ...

  3. JS原生隐士标签扩展

    最近项目开发中,开发了不少的接口,有一个接口是这样子的.先从A公司拿到数据后,存放到我们公司数据库里,然后需要将数据展示给客户,下面这个界面,后台要实时刷新,后台写了个定时器,2S刷一次从后台拼接好H ...

  4. 编写自定义 .NET Core 主机以从本机代码控制 .NET 运行时

    自定义 .Net Core 主机运行.Net Core代码,以及控制运行时运行状态,是在.Net Core 高级运行环境以及定制.Net Host ,CLR 等必不可少的. 这些设置包括为     1 ...

  5. 数据类型之Integer与int

    数据类型之Integer与int Java入门  基本数据类型 众所周知,Java是面向对象的语言,一切皆对象.但是为了兼容人类根深蒂固的数据处理习惯,加快常规数据的处理速度,提供了9种基本数据类型, ...

  6. go 学习笔记之工作空间

    搭建好 Go 的基本环境后,现在可以正式开始 Go 语言的学习之旅,初学时建议在默认的 GOPATH 工作空间规范编写代码,基本目录结构大概是这个样子. . |-- bin | `-- hello.e ...

  7. 有趣的Flex布局

    对于刚接触前端的小白,在还原页面样式的时候,往往会遇到页面布局(layout)上的问题,用着生硬的padding来固定盒子的位置,不仅代码看的沉重,还得适应各种浏览器页面,始终没有办法做到统一.接下来 ...

  8. 2019上半年总结——Github上那些Java面试、学习相关仓库

    分享一下最近逛Github看到了一些对于Java面试以及学习有帮助的仓库,这些仓库涉及Java核心知识点整理.Java常见面试题.算法.基础知识点比如网络和操作系统等等. 知识点相关 1.JavaGu ...

  9. 使用 OpenSSL 为 Nginx 创建自签名证书 并开启客户端身份验证

    本文章默认读者了解Openssl,CA,网站证书相关知识,直接实战!配置完成后,浏览器会显示"安全的HTTPS"连接.不会像其他文章那样,是红色警告的证书提示. 准备环境 笔者使用 ...

  10. jQuery插件之路(一)——试着给jQuery的一个Carousel插件添加新的功能

    前几日在网上看到了一个关于Carousel插件的教学视频,于是也顺便跟着学习着做了一下.但是在做完之后发现,在别的网站上面看到类似的效果要比现在做的这个要多一个功能,也就是在底下会有一些按钮,当鼠标放 ...