今天重新看了一点周志明大佬的《深入理解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. python代理池的构建2——代理ip是否可用的处理和检查

    上一篇博客地址:python代理池的构建1--代理IP类的构建,以及配置文件.日志文件.requests请求头 一.代理ip是否可用的处理(httpbin_validator.py) #-*-codi ...

  2. 如何用 4 个小时搭建一个新 “Clubhouse” ,引爆声音社交新风口

    Clubhouse,基于实时音频技术的声音社交现象级火爆 最近,让硅谷两位顶级 VC 大打出手争相投资的 Clubhouse 火到了国内,甚至在社交圈里 "一码难求",此种火爆程度 ...

  3. 004、Python xlsxwriter模块

    简单用法demo # !/usr/bin/python # coding:utf-8 # xlsxwriter的基本用法 import xlsxwriter # 1. 创建一个Excel文件 work ...

  4. 洛谷p1725 露琪诺 单调队列优化的DP

    #include <iostream> #include <cstdio> #include <cstring> using namespace std; int ...

  5. Windows font-size: 10px; bug

    Windows font-size: 10px; bug Windows 最小只能渲染 font-size: 12px; ???屏幕分辨率 macOS 正常渲染 10px PC 最小只能渲染 font ...

  6. webpack remove console.log

    webpack remove console.log https://stackoverflow.com/questions/41040266/remove-console-logs-with-web ...

  7. React Fragment All In One

    React Fragment All In One React还提供了一个无需包装即可呈现多个元素的组件. https://reactjs.org/docs/react-api.html#fragme ...

  8. React Refs All In One

    React Refs All In One https://reactjs.org/docs/react-api.html#refs Ref https://reactjs.org/docs/refs ...

  9. ES6 Generator vs ES6 async/await

    ES6 Generator vs ES6 async/await next yield promise refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允 ...

  10. nasm astrchr函数 x86

    xxx.asm: %define p1 ebp+8 %define p2 ebp+12 %define p3 ebp+16 section .text global dllmain export as ...