下方代码主要说明:

String b = new String("xyz")  创建2个对象,一个在常量池中的 "xyz",一个 String 实例对象,返回的是实例对象引用。

intern() 方法有两个作用,一是取出 String Pool 中的值(可能是字面量可能是引用),二是如果 String Pool 没有该值,则将String 对象引用添加到 String Pool

String a = "abc"  该表达式有两个作用,一是取出 String Pool 中的值并返回(可能是字面量可能是对象的引用),二是如果 String Pool 没有该值,则将 字面量添加到 String Pool

检测代码:

public class Test {

    @org.junit.Test
public void test() { String s1 = new String("x") + new String("yz");
//这里的 new String 会创建5个对象,3个实例,2个字面量,存入 "x", "yz" 2 个字面量。
//返回 "xyz" 的引用
String l_s1 = s1.intern(); //当常量池中没有该字面量或引用时,则把该字符串对象的引用添加到常量池中,并返回引用
String s2 = "xyz"; printHash(l_s1); //引用
printHash(s1); //引用
printHash(s2); //当常量中有该字符串的引用,返回引用 String s3 = new String("abc"); //生成 2个对象,1个实例,1个 "abc" 字面量。存入 "abc" 字面量,返回 "abc" 引用
String s4 = "abc";
String l_s3 = s3.intern(); //与前面对比,可知常量池中确实有该字符串,返回的是字面量 printHash(l_s3); //字面量
printHash(s3); //引用
printHash(s4); //字面量 String s = "s"; //存入该字面量,返回该字面量
printHash(s.intern()); //字面量
printHash(s); //字面量
} private void printHash(String str) {
int hash = System.identityHashCode(str);
System.out.println(str.hashCode() + " : " + hash);
} }

返回结果:

119193 : 476800120
119193 : 476800120
119193 : 476800120
96354 : 1744347043
96354 : 1254526270
96354 : 1744347043
115 : 662441761
115 : 662441761

下方代码说明:

new String("xyz") 会生成 2 个对象,而 new String(bytes) 只生成一个对象

检测代码

public class Test {

    @org.junit.Test
public void test() {
char[] bytes = new char[]{'a', 'b', 'c'};
String s1 = new String(bytes);
String l_s1 = s1.intern();
String s2 = "abc";
printHash(s1);
printHash(l_s1);
printHash(s2); String s3 = new String("xyz");
String l_s3 = s3.intern();
String s4 = "abc";
printHash(s3);
printHash(l_s3);
printHash(s4);
} private void printHash(String str) {
int hash = System.identityHashCode(str);
System.out.println(str.hashCode() + " : " + hash);
} }

返回结果

96354 : 476800120
96354 : 476800120
96354 : 476800120
119193 : 1744347043
119193 : 1254526270
96354 : 476800120

总结:

在不同情况下 new String(param) 方法或 "abc" 会生成字面量与引用。那么考虑一般情况,在使用 new String("abc") 或 String s = "abc" ,通常会生成字面量。使用 new String(bytes) 通常不会自动生成字面量,需要调用 new String(bytes).intern()  方法。

补充:

1. 对象的 hashCode 方法与 System.identityHashCode 区别 :一般情况下 hashCode 等同于 identityHashCode。但是由于下一条中的因素,会导致不相等。

2. 当对象的 equals 方法重写时,也需要正确重写对象的 hashCode 方法。一个原则是,equals 相等,hashCode 必须相等。而 hashCode 相同,equals 可以不相等。在该对象作为字典中的 key 涉及到 Hash 存取时,判断是否相等先使用 hashCode  判断,再使用 equals 判断,这样可以提高效率。(分析见 参考


jdk6 的比较请参考

Java 中 String 的字面量与 intern 方法的更多相关文章

  1. 【译】Java中的字符串字面量

    原文地址:https://javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html 作者:Corey McGlone 让我们由一个简 ...

  2. Java中String推断相等equals与==的差别以及StringBuilder的equals

    Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的"相等"有所不同,接下来进行分析,结论由程序进行验证 Str ...

  3. Java - String 的字面量、常量池、构造函数和intern()函数

    一.内存中的 String 对象 Java 的堆和栈 对于基本数据类型变量和对象的引用,也就是局部变量表属于栈内存: 而通过 new 关键字和 constructor 创建的对象存放在堆内存: 直接的 ...

  4. String 的字面量、常量池、构造函数和intern()函数

    一.内存中的 String 对象 Java 的堆和栈 对于基本数据类型变量和对象的引用,也就是局部变量表属于栈内存: 而通过 new 关键字和 constructor 创建的对象存放在堆内存: 直接的 ...

  5. Java常量,变量,对象(字面量)在JVM内存中的存储位置

    Java常量,变量,对象(字面量)在JVM内存中的存储位置 2019-02-26 18:13:09 HD243608836 阅读数 540  收藏 更多 分类专栏: JAVA jvm   苦苦研究了快 ...

  6. Java中String字符串常量池总结

    最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...

  7. 【java基础】java中String的注意点

    [java的内存模型] 一.Java内存模型 按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两种类型内存:堆和非堆,堆内存(Hea ...

  8. Java中String的设计

    String应用简介 前言 String字符串在Java应用中使用非常频繁,只有理解了它在虚拟机中的实现机制,才能写出健壮的应用,本文使用的JDK版本为1.8.0_111. 常量池 Java代码被编译 ...

  9. Java 中 String 的构造方法

    String 对于所有 Java 程序员来说都不会陌生,几乎每天甚至每个程序都会和 String 打交道,因此将 String 的常用知识汇集在此,方便查阅. 概叙: Java 中是如此定义 Stri ...

随机推荐

  1. [再寄小读者之数学篇](2014-06-23 Bernstein's inequality)

    $$\bex \supp \hat u\subset \sed{2^{j-2}\leq |\xi|\leq 2^j} \ra \cfrac{1}{C}2^{jk}\sen{f}_{L^p} \leq ...

  2. burp suite 基础入门超详细教程

    介绍: 都是我个人了解到的信息,,分享给大家 欢迎指正 burp suite 被誉为web安全工具中的瑞士军刀. 大家知道,瑞士军刀,都是体积小,功能强悍,.西方军队的标配.说这么多,只是想强调这款工 ...

  3. 拖动DIV

    链接:https://www.cnblogs.com/joyco773/p/6519668.html   移动端:div在手机页面上随意拖动   1 <!doctype html> 2 & ...

  4. Python学习笔记-Linux下安装Python

    Linux系统CentOS 1.安装依赖组件 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel s ...

  5. Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column

    安装了mysql5.7.19后,执行语句中只要含有group by 就会报这个错 [Err] 1055 - Expression #1 of ORDER BY clause is not in GRO ...

  6. 简单使用Markdown

    Markdown是一种纯文本格式的标记语言.通过简单的标记语法,它可以使普通文本内容具有一定的格式. 相比WYSIWYG编辑器 优点: 1.因为是纯文本,所以只要支持Markdown的地方都能获得一样 ...

  7. 可持久化 trie 的简单入门

    可持久化 $trie$  ....又是一个表里不一的东西..... 可持久化 $trie$  的介绍: 和主席树类似的,其实可持久化就是体现在前缀信息的维护上(搞不懂这怎么就叫做可持久化了...) $ ...

  8. Innodb和Myisam数据恢复

    (转自)https://www.cnblogs.com/DwyaneTalk/p/4113829.html 背景 这次恢复oracle和sqlserver,想想也不能把mysql落下了吧.三剑合一.都 ...

  9. JavaScript入门学习笔记(异常处理)

    try:语句测试代码块的错误,当try中的代码块出错时执行catch中的代码块. catch:语句处理错误: throw:语句创建或抛出自定义异常. 三者一起使用可以控制程序流并生成自定义异常信息. ...

  10. js定义数组集合

    简单描述:最近脑子有点抽,js要用到数组,竟然傻傻的写了 var [] str = .简直是糟糕的不要不要的 //js代码var str = [];var str =new Array(); 啥也不说 ...