今天重新看了一点周志明大佬的《深入理解Java虚拟机》,发现这个地方讲的不是很透彻,在网络上看到一些博客基本也都是在搬运原文,搞得一头雾水。弄了半天算是彻底明白了,做一下笔记。

搬运一下原文对intern()方法的说明:String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用(指的是常量池中的实例);否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用(指的是堆中的实例)。括号中是我的个人理解,由于作者两种情况说的结果都是"String对象的引用",让我错误地理解为都是堆中实例的引用。接下来我们看几段代码。

String a = "a";
String b = new String("a");
System.out.println(a == b);

上面这段代码结果显然是false,虽然两者值相等,但是a是字面量(常量池中),b在堆中(因为b是通过new创建)。

接下来我们看书中的这个例子:

String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2);

结果是true,false。解释如下:"计算机软件"从未出现在常量池,因此str1.intern()的结果为堆中的值为"计算机软件"的String对象,同时也会将"计算机软件"这个字符串加入到常量池中;"java"曾出现在sun.misc.Version这个类中,因此早就存在于常量池里,所以str2.intern()的结果为常量池中的值为"java"的字面量。

再看看以下代码段:

String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str2.intern() == str2);

结果是true,false。这说明第一个intern()将"计算机软件"这个字符串加入到了常量池中,导致str2.intern()实际上是在常量池中,而str2在堆中。

String str1 = new String("计算机软件");
System.out.println(str1.intern() == str1);

这个结果是false,因为这样的构建String的方法会做两件事:在常量池中创建一个实例,再复制到堆中创建一个对象。这就导致str1.intern()实是在常量池中,而str1在堆中。

String str1 = new String("计算机软件");
System.out.println(str1.intern() == "计算机软件");

而这个结果是true,就很好理解了。

对String Intern()方法的理解的更多相关文章

  1. String放入运行时常量池的时机与String.intern()方法解惑

    运行时常量池概述 Java运行时常量池中主要存放两大类常量:字面量和符号引用.字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为final的常量值等. 而符号引用则属于编译原理方面的概念 ...

  2. 浅析String.intern()方法

    1.String类型“==”比较样例代码如下:package com.luna.test;public class StringTest { public static void main(Strin ...

  3. 常量池之String.intern()方法

    JDK7将String常量池从Perm区移动到了Java Heap区.在JDK1.6中,intern方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中的实例.但是在JDK1.7以后,Str ...

  4. 深入理解String.intern()方法

    首先进入intern()的源码中, 首先说一点:1.7后的JVM为String在方法区中开辟了一个字符串常量池,如果一个String()不是new()出来的,都将在常量池中拿字符. 注释翻译过来就是, ...

  5. 关于对String中intern方法的理解

    在java的String中有个一直被我们忽视了的方法intern方法:它的官方解释是:一个初始时为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于 ...

  6. String intern 方法 jdk中的描述

    一个初始为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中 ...

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

    1.为什么要使用intern()方法 intern方法设计的初衷是为了重用string对象,节省内存 用代码实例验证下 public class StringInternTest { static f ...

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

    字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 pub ...

  9. String intern()方法详解

    执行以下代码 String a1=new String("abc");       String a2=new String("abc");       Sys ...

随机推荐

  1. WSL2 Ubuntu apt-get update失败

    情况: 这个问题在github上也有讨论:https://github.com/microsoft/WSL/issues/4342 不过经过我的尝试,是DNS问题,这是默认的配置: 这个配置来自win ...

  2. Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  3. Python_变量作用域与修改

    引用全局变量,不需要golbal声明,修改全局变量,需要使用global声明,特别地,列表.字典等如果只是修改其中元素的值(而不是整体赋值的形式),可以直接使用全局变量,不需要global声明. 参考 ...

  4. codeforces 870C

    C. Maximum splitting time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  5. Win7环境下mysql报错1045:Access denied for user root@localhost错误解决方法

    产生场景:在涉及到连接数据库操作的时候,会报1045:Access denied for user root@localhost. 比如:本地建立的数据库连接不上,在IDEA等开发工具中使用反向生成. ...

  6. μC/OS-III---I笔记9---任务等待多个内核对象和任务内建信号量与消息队列

    在一个任务等待多个内核对象在之前,信号量和消息队列的发布过程中都有等待多个内核对象判断的函数,所谓任务等待多个内核对象顾名思义就是一任务同时等待多个内核对象而被挂起,在USOC-III中一个任务等待多 ...

  7. Install wx

    Ubuntu 16.04: 由于是PY交易, 实际上是安装wxPython: pip install -U \ -f https://extras.wxpython.org/wxPython4/ext ...

  8. DNS & HTTPS bug

    DNS & HTTPS bug SSL protocol version bug https://typescript-4.x-tutorials.xgqfrms.xyz/ errors Th ...

  9. js sort map by key

    js sort map by key Map map to array // Array.from() Object let obj = {}; for(let key of Object.keys( ...

  10. node.js & ORM & ODM

    node.js & ORM & ODM ODM & NoSQL Object Data Modeling 对象数据模型 Object Document Mapping 对象文档 ...