官方API:
intern

public String intern()

返回字符串对象的规范化表示形式。

一个初始时为空的字符串池,它由类 String 私有地维护。

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。

它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

所有字面值字符串和字符串赋值常量表达式都是内部的。

返回:

一个字符串,内容与此字符串相同,但它保证来自字符串池中。

------------------------------------------------------------------------------------------------

我们知道,一个Java程序运行后,String类会在内存的方法区中维护一个字符串池。对一个字符串调用intern()方法后,会先检查池内是否有该字符串,若有则返回;若没有没有则先创建再返回,确保返回的字符串已经以字面量的形式存在于池中。

上测试样例代码:

public class Test {public static void main(String argv[]){String s1 = "HelloWorld";String s2 = new String("HelloWorld");String s3 = "Hello";String s4 = "World";String s5 = "Hello" + "World";String s6 = s3 + s4;System.out.println(s1 == s2);System.out.println(s1 == s5);System.out.println(s1 == s6);System.out.println(s1 == s6.intern());System.out.println(s2 == s2.intern());}
}

测试结果:

false

true

false

true

false

解释一下:s1 创建的 HelloWorld 存在于方法区中的常量池其中的字符串池,而 s2 创建的 HelloWorld 存在于堆中,故第一条 false 。

s5 的创建是先进行右边表达式的字符串连接,然后才对 s5 进行赋值。赋值的时候会搜索池中是否有 HelloWorld 字符串,若有则把 s5 引用指向该字符串,若没有则在池中新增该字符串。显然 s5 的创建是用了 s1 已经创建好的字面量,故 true 。

第三个比较容易弄错,s6 = s3 + s4; 其实相当于 s6 = new String(s3 + s4); s6 是存放于堆中的,不是字面量。所以 s1 不等于 s6 。

第四个 s6.intern() 首先获取了 s6 的 HelloWorld 字符串,然后在字符串池中查找该字符串,找到了 s1 的 HelloWorld 并返回。这里如果事前字符串池中没有 HelloWorld 字符串,那么还是会在字符串池中创建一个 HelloWorld 字符串再返回。总之返回的不是堆中的 s6 那个字符串。

第四条也能解释为什么第五条是 false 。s2是堆中的 HelloWorld,s2.intern() 是字符串池中的 HelloWorld 。

--------------------------------------------------------------

在多一句,如果把

String s6 = s3 + s4;
改成

String s6 = (s3 + s4).intern();

会发生什么呢?

s6 存储的 HelloWorld 是存放字符串池中还是堆中呢?

答案是前者。

另外:

// jdk1.6
// false、true、false、true、false、true
// jdk1.7
// false、true、true、true、false、true
// jdk1.8
// false、true、true、true、false、true
String str1 = new StringBuffer("ja").append("va").toString();
String intern1 = str1.intern();
System.out.println(intern1 == str1);
System.out.println(intern1.equals(str1));
String str2 = new StringBuffer("我是").append("中国人").toString();
String intern2 = str2.intern();
System.out.println(intern2 == str2);
System.out.println(intern2.equals(str2));
String str3 = new StringBuffer("我是").append("中国人").toString();
String intern3 = str3.intern();
System.out.println(intern3 == str3);
System.out.println(intern3.equals(str3));
/*** "java"字符串常量比较特殊,它是固定存在字符串常量池中,所以都是返回了false* Java6中字符串常量池是在永久代区,intern方法会将首次遇到的字符串复制到那里,返回的也是永久代中这个字符串的引用。不建议使用这个方法。* Java7中字符串常量池被放到了堆中,intern的实现也不再是复制实例,只是在常量池中记录首次出现的实例引用。* Java8同7一致*/

代码解释:

(1)java1.6

str1、str2和str3都是指向堆内存的地址;

intern1、intern2和intern3都是指向永生代的常量池地址;

所以,“==”的地址比较肯定都是false,但是equals比较的都是内容,所以都是true;

(2)java1.7

str1、str2和str3都是指向堆内存的地址

由于“java”字符串的特殊性,intern1指向的常量池的地址,所以第一个地址的比较就是false;

intern2和str2都是指向同一块堆地址,所以第二个地址的比较就是true;

由于str3的字符串已经在常量池中存在,所以intern3就和intern2、str2的地址保持一致;

原文:

https://blog.csdn.net/wjzhang5514/article/details/70209403

https://blog.csdn.net/qq_39305860/article/details/79645664

String的intern()方法详解相关推荐

  1. String类的intern()方法详解

    0.引言 什么都先不说,先看下面这个引入的例子: [java] view plaincopy String str1 = new String("SEU")+ new String ...

  2. String类中的intern()方法详解

    来源地址:https://blog.csdn.net/soonfly/article/details/70147205 在翻<深入理解Java虚拟机>的书时,又看到了2-7的 String ...

  3. java的intern()方法详解

    尽管在输出中调用intern方法并没有什么效果,但是实际上后台这个方法会做一系列的动作和操作.在调用"ab".intern()方法的时候会返回"ab",但是这个 ...

  4. 序列内置方法详解(string/list/tuple)

    一.常用方法集合 1.1.string,字符串常用方法 以下举例是python2.7测试: 函数名称 作用 举例 str.capitalize() 字符串第一个字符如果是字母,则把字母替换为大写字母. ...

  5. String.format()方法详解

    String.format()方法详解 前言: String.format()作为文本处理工具,为我们提供强大而丰富的字符串格式化功能,这里根据查阅的资料做个学习笔记,整理成如下文章,供后续复习查阅. ...

  6. java的String类源码详解

    java的String类源码详解 类的定义 public final class Stringimplements java.io.Serializable, Comparable<String ...

  7. Spring JdbcTemplate方法详解

    2019独角兽企业重金招聘Python工程师标准>>> Spring JdbcTemplate方法详解 标签: springhsqldbjava存储数据库相关sql 2012-07- ...

  8. golang 解析php序列化,golang实现php里的serialize()和unserialize()序列和反序列方法详解...

    Golang 实现 PHP里的 serialize() . unserialize() 安装 go get -u github.com/techleeone/gophp/serialize 用法 pa ...

  9. java构造和解析json_Java构造和解析Json数据的两种方法详解一

    在www.json.org上公布了很多JAVA下的json构造和解析工具,其中org.json和json-lib比较简单,两者使用上差不多但还是有些区别.下面首先介绍用json-lib构造和解析Jso ...

  10. java多线程中的join方法详解

    java多线程中的join方法详解 方法Join是干啥用的? 简单回答,同步,如何同步? 怎么实现的? 下面将逐个回答. 自从接触Java多线程,一直对Join理解不了.JDK是这样说的:join p ...

最新文章

  1. 转载一个关于JavaScript几种继承方法的总结
  2. pinctrl 和 gpio 子系统
  3. ASI和AFN的区别
  4. 火狐浏览器修改userAgent
  5. 10-3的随笔继续讲,演绎“圆弧底”
  6. 08.为什么要使用lombok,它解决了什么问题?
  7. powerpoint(ppt) 的制作
  8. 常见移动机器人多角度对比分析
  9. java炫酷龙卷风源码,龙卷风's Blog
  10. rsync udr——远程大文件传输加速
  11. 阿里国际站各数据更新时间汇总
  12. [转]大规模服务设计部署经验谈
  13. 面向过程(PO)和面向对象(OO)的区别(思维导图)
  14. 有特色的出版社图书封面
  15. 多传感器数据融合发展综述
  16. LeetCode题解系列--309. Best Time to Buy and Sell Stock with Cooldown
  17. 一.对于crc校验的流程演示说明。
  18. 备考通信复试过程中的一些知识点总结梳理——移动通信系统Ⅱ
  19. 学习上溯造型和下溯造型 【转载一篇】
  20. python自动打卡

热门文章

  1. 图论·并查集·题解【Cow at Large G·atlarge】
  2. 敏感词过滤的算法原理之 Aho-Corasick 算法
  3. 干货!量子技术入门、进阶、行业专家观点、最新资讯!1000篇好文帮你揭开量子技术神秘面纱!...
  4. LED白光测速仪MSE-V508
  5. 【吴恩达】机器学习第16章异常检测以及ex8部分编程练习
  6. mybatis框架xml中trim中的prefix与suffix等标签的作用
  7. android百度地图3d路线,百度地图Android V2.0新增卫星图及3D模式功能
  8. 手把手教你搭建SpringCloud项目(三)集成Eureka服务注册中心
  9. win8系统电脑使用技巧的详细介绍--win7w.com
  10. 光盘怎么刻录服务器系统,如何刻录系统光盘?小编手把手教你电脑Windows刻录系统光盘的方法...