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. 装饰器和"开放-封闭"原则

    装饰器和"开放-封闭"原则 "开放-封闭"原则 软件开发中的"开放-封闭"原则,它规定已经实现的功能代码不应该被修改,但可以被扩展,即: 封 ...

  2. 【iOS】PLA 3.3.12

    发件人 Apple Program License Agreement PLA We found that your app uses the Advertising Identifier but d ...

  3. Java equal() 和 == 详细分析

    1 ==  返回值是true/false; (1) 基本数据类型比较的就是值(2)引用型数据类型就是地址值 public class Test1 { public static void main(S ...

  4. 进军pc市场 华为剑走偏锋可有戏?

    尽管官方并未正式公布,但在前段时间,华为将要进军PC市场的消息在业内传得沸沸扬扬,据知情人士曝料,其第一款个人电脑将在今年4月上线.而华为将进军PC市场的消息,对其他智能手机厂商来说又意味着什么呢? ...

  5. java之Arrays.asList

    使用Arrays.asList()的原因无非是想将数组或一些元素转为集合,而你得到的集合并不一定是你想要的那个集合. 而一开始asList的设计时用于打印数组而设计的,但jdk1.5开始,有了另一个比 ...

  6. restapi(4)- rest-mongo : MongoDB数据库前端的httpserver

    完成了一套标准的rest风格数据库CRUD操作httpserver后发现有许多不足.主要是为了追求“通用”两个字,想把所有服务接口做的更“范generic”些,结果反而限制了目标数据库的特点,最终产生 ...

  7. 解决 Android 中出现依赖多个版本支持库的问题

    在 app 的 build.gradle 中引入依赖时发现如下错误: All com.android.support libraries must use the exact same version ...

  8. koa2图片上传成功后返回服务器地址,实时显示服务器图片

    版本:node(8.5.0); koa(2.4.1); koa-router(7.3.0); koa-body(2.5.0); koa-static(4.0.2); 代码实现 const fs = r ...

  9. struts的上传下载

    文件上传 添加jar包 commons-io-1.3.2.jar commons-fileupload-1.2.1.jar 前台页面 form表单 method值为post 添加"encty ...

  10. 单机版ZooKeeper的安装教程

    之前一直没有时间去整理,现在抽出几分钟时间整理以下,有问题的在评论区留言即可. 前期准备JDK环境(ZK需要jdk进行编译,本文以jdk1.8.0_211为例).Linux系统(本文以Centos7为 ...