一、概述

JDK7 之前和之后的版本,String 的 intern() 方法在实现上存在差异,本文的说明环境是 JDK8,会在文末说明 intern() 方法的版本差异性。

intern() 方法是一个 native 的方法,返回常量池中的字符串引用,主要体现在以下两点:

  1. 如果常量池中已存在该字符串,则直接返回常量池中该对象的引用。
  2. 如果常量池中不存在该字符串,则在常量池中加入该对象引用并返回。

二、示例说明

一般我们创建字符串的方式有以下三种:

  1. 字面量创建方式,例如 String s = "java"
  2. new String() 创建方式,例如 String s = new String("java")
  3. StringBuilder/StringBuffer 创建方式,例如 String s = new StringBuilder("ja").append("va").toString()

字面量创建方式,会在字符串常量池中创建字符串实例,并返回该引用;new String() 和 StringBuilder/StringBuffer 创建方式都是在堆(Heap)上创建字符串实例,并返回该引用。

public class StrIntrenTest {

    public static void main(String[] args) {
// 1. 字面量创建形式
String s1 = "jmcui";
// 1. 在字符串常量池中生成字符串【"jmcui"】实例
// 2. 将栈中的 s1 指向字符串常量池中的字符串【"jmcui"】实例 System.out.println("s1 == s1.intern() :" + (s1 == s1.intern())); // true // 2. new 创建方式
String s2 = new String("jmcui");
// 1. 在Java堆中生成字符串【"jmcui"】实例
// 2. 将栈中的 s2 指向Java堆中的字符串【"jmcui"】实例 System.out.println("s1 == s2 :" + (s1 == s2)); // false
System.out.println("s1.equals(s2) :" + s1.equals(s2)); // true
System.out.println("s1 == s2.intern():" + (s1 == s2.intern())); // true // 3. StringBuilder/StringBuffer 方式和 new 方法类似
String s3 = new StringBuilder("jm").append("cui").toString();
// 1. 在Java堆中生成字符串【"jmcui"】实例
// 2. 将栈中的 s3 指向Java堆中的字符串【"jmcui"】实例
System.out.println("s1 == s3 :" + (s1 == s3)); // false
System.out.println("s2 == s3 :" + (s2 == s3)); // false
System.out.println("s2.intern() == s3.intern() :" + (s2.intern() == s3.intern())); // true
}
}
  • s1 == s1.intern() 返回 true,因为字面量的创建方式是在字符串常量池中生成实例,而 intern() 方法返回常量池中的字符串引用,两个引用自然是同一个。
  • s1 == s2 返回 false,因为 new String() 的方式是在堆(Heap)上创建实例,二者不是同一个引用。
  • s1.equals(s2) 返回 true,equals 方法是用来比较的是两个字符串的内容是否相等。
  • s1 == s2.intern() 返回 true,当 s2 调用 intern() 方法的时候,发现常量池中已经存在该字符串,则直接返回了该引用(s1 的引用)。
  • s1 == s3 返回 false, StringBuilder/StringBuffer 创建方式是在堆(Heap)上创建字符串实例,二者不是同一个引用。
  • s2 == s3 返回 fasle,s2 和 s3 都是 new 出来的字符串实例,在堆(Heap)上存储不同的位置,自然不是同一个实例。
  • s2.intern() == s3.intern() 返回 true,前面说明 s2 的 intern() 返回的是 s1 的引用,s3 的 intern() 也是一样的道理,因此 s2 的 intern() 和 s2 的 intern() 返回的都是 s1 的引用,所以相等。

三、和 JDK6 的版本差异

JDK7 之后的 intern() 方法和之前版本的差异主要体现在:如果常量池中不存在该字符串时的处理机制。

JDK7 之后的版本,如果常量池中不存在该字符串,则在常量池中加入该对象引用并返回。注意,关键词 — 加入对象引用!

JDK7 之前的版本呢?它的处理机制是,如果常量池中不存在该字符串,则在常量池中新建一个字符串实例并返回该实例引用。关键词:新建实例!

String 的 intern() 方法解析的更多相关文章

  1. java String 中 intern方法的概念

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...

  2. String 的intern() 方法说明

    1.说明 Java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,就会在字符串常量池中创建该字符串然后再返回. 2.源码说明 public native ...

  3. String中intern方法的作用

    前言 读完这篇文章你可以了解,String对象在虚拟机内存中的存放,intern的作用,这么多String对象的创建到底有什么区别,String 创建的对象有几个!! 正题 先科普几个知识点1.常量池 ...

  4. String的intern方法的使用场景

    在讲intern方法前,我们先简单回顾下Java中常量池的分类. 常量池的分类 Java中常量池可以分为Class常量池.运行时常量池和字符串常量池. 1. Class文件常量池 在Class文件中除 ...

  5. String的intern方法的用处

    今天第一次翻看Effective java,在其第一个item中讲静态工厂方法的有点的时候说到“它们每次被调用 的时候,不要非得创建一个新的对象”并在结尾处提到---"String.inte ...

  6. String的Intern方法详解

    引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念.常量池就类似一个JAVA系统级别提供的缓存.8种 ...

  7. String的Intern方法

    jdk6 和 jdk7 下 intern 的区别 相信很多 JAVA 程序员都做做类似 String s = new String("abc")这个语句创建了几个对象的题目. 这种 ...

  8. java String的intern()方法

    intern()方法用于将字符串对象加入常量池中. public native String intern(); intern()方法返回的是一个常量池中的String对象(即常量池中某个String ...

  9. Java - 记录String中intern()方法的学习与理解

    intern()方法:把堆中的引用丢入常量池中,然后返回这个引用.当常量池中已经存在这个引用,就直接返回这个引用.(jdk1.8) 由于jdk1.7中将字符串常量池改为存放在堆中,因此intern() ...

随机推荐

  1. python基础-网络编程part02

    TCP协议 TCP是传输控制协议,建立双向通道. 三次握手,建立连接 客户端向服务端发送建立连接的请求 服务端接收请求返回确认信息给客户端,并向客户端发送建立连接的请求 客户端接收请求返回确认信息给服 ...

  2. SpringBoot写一个登陆注册功能,和期间走的坑

    文章目录 前言 1. 首先介绍项目的相关技术和工具: 2. 首先创建项目 3. 项目的结构 3.1实体类: 3.2 Mapper.xml 3.3 mapper.inteface 3.4 Service ...

  3. CSS+HTML实现移动端div左右滑动展示

    由于手机屏幕的宽度有限,内容太多移动设备一行装不下的,所以很多移动端网站的导航栏都有左右滑动效果,下面我就用CSS+HTML实现移动端div左右滑动展示. CSS:box设置文本不换行,子元素box1 ...

  4. shell 替换文本中的某个符号为换行符

    替换后为: 0.06774 脚本: :%s/,"/\r/g

  5. gitlab 命令使用

    利用 rm -rf 误删除文件夹, 恢复的办法(注意 要 提前备份或提交 其他新改变的代码, 否则执行下面的命令会让之前的新代码全部消失): git status git reset HEAD \* ...

  6. 基于webpack实现多html页面开发框架八 html引入图片打包和公共页面模块复用

    一.解决什么问题 1.html中img引入的图片地址没有被替换,找不到图片 2.html公共部分复用问题,如头部.底部.浮动层等 二.html中img引入图片问题解决 1.在index.html插入i ...

  7. 制作通用framework的几点注意

    一.创建framework,调成静态的framework . 二.匹配bitcode 三.增加-ObjC 在BuildSettting ->Linking->Other Linker Fl ...

  8. 笔记||Python3之算法

    循环嵌套:先从外层循环里面取出一个元素,再执行内层的循环:当内层的循环都执行后,再执行外层循环. for循环嵌套语法: for  x  in  range(): for  y  in  range() ...

  9. 【性能优化】404- 从 12.67s到1.06s 性能优化实战

    作者:jerryOnlyZRJ 来源:https://juejin.im/post/5b6fa8c86fb9a0099910ac91 本文是对之前同名文章的修正,将所有webpack3的内容更新为we ...

  10. 一文搞清楚Minor GC、Major GC 、Full GC 之间的关系

    前言 文章要求读者熟悉 JVM 内置的通用垃圾回收原则.堆内存划分为 Eden.Survivor 和 Tenured/Old 空间,代假设和其他不同的 GC 算法超出了本文讨论的范围. Minor G ...