今天重新看了一点周志明大佬的《深入理解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. vs2019激活码

    Visual Studio 2019 Enterprise BF8Y8-GN2QH-T84XB-QVY3B-RC4DF Visual Studio 2019 Professional NYWVH-HT ...

  2. ElasticSearch 集群 & 数据备份 & 优化

    ElasticSearch 集群相关概念 ES 集群颜色状态 ①. - 红色:数据都不完整 ②. - 黄色:数据完整,但是副本有问题 ③. - 绿色:数据和副本全都没有问题 ES 集群节点类型 ①. ...

  3. leetcode32 最长游戏括号 dp

    有一说一,我觉得这题没有到困难级 要保存之前的状态,感觉是很明显的dp 思路和题解一样 class Solution { public: int longestValidParentheses(str ...

  4. 网络流学习-Ford-Fulkerson

    首先我们先解决最大流问题 什么是最大流问题呢 根据我的理解,有一个源点s,汇点t,s可以通过一个网络(雾)流向汇点t 但是每一条边都有他的最大传输容量限制,那么我们的任务是,如何分配流量使得..从s流 ...

  5. Linux 驱动框架---驱动中的异步

    异步IO是对阻塞和轮询IO的机制补充,所谓异步IO就是在设备数据就绪时主动通知所属进程进行处理的机制.之所以说是异步是相对与被通知进程的,因为进程不知道也无法知道什么时候会被通知:这一机制非常类似于硬 ...

  6. TypeScript Errors All In One

    TypeScript Errors All In One 1. Property 'name' has no initializer and is not definitely assigned in ...

  7. JavaScript for, for...in, for...of, for-await...of difference All In One

    JavaScript for, for...in, for...of, for-await...of difference All In One for for...in for...of for-a ...

  8. Android混合Flutter

    官方文档 实验性:将Flutter添加到Android 测试仓库 取决于模块的源代码 方法测试成功

  9. Dart http库

    推荐下我写的一个http库ajanuw_http 最基本的获取数据 import 'package:http/http.dart' as http; main(List<String> a ...

  10. 基于NGK发行的稳定币USDN如何撼动市场?

    近日,基于NGK发行的稳定币USDN在各大社区的热度越来越高,很多人都说USDN将会撼动市场,那么USDN究竟有怎样的优势,能引起这么大的轰动呢?今天我们就一起来分析一下USDN. USDN是基于公链 ...