对String Intern()方法的理解
今天重新看了一点周志明大佬的《深入理解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()方法的理解的更多相关文章
- String放入运行时常量池的时机与String.intern()方法解惑
运行时常量池概述 Java运行时常量池中主要存放两大类常量:字面量和符号引用.字面量比较接近于Java语言层面的常量概念,如文本字符串.声明为final的常量值等. 而符号引用则属于编译原理方面的概念 ...
- 浅析String.intern()方法
1.String类型“==”比较样例代码如下:package com.luna.test;public class StringTest { public static void main(Strin ...
- 常量池之String.intern()方法
JDK7将String常量池从Perm区移动到了Java Heap区.在JDK1.6中,intern方法会把首次遇到的字符串实例复制到永久代中,返回的也是永久代中的实例.但是在JDK1.7以后,Str ...
- 深入理解String.intern()方法
首先进入intern()的源码中, 首先说一点:1.7后的JVM为String在方法区中开辟了一个字符串常量池,如果一个String()不是new()出来的,都将在常量池中拿字符. 注释翻译过来就是, ...
- 关于对String中intern方法的理解
在java的String中有个一直被我们忽视了的方法intern方法:它的官方解释是:一个初始时为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于 ...
- String intern 方法 jdk中的描述
一个初始为空的字符串池,它由类 String 私有地维护. 当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中 ...
- String.intern() 方法__jdk1.6与jdk1.7/jdk1.8的不同
1.为什么要使用intern()方法 intern方法设计的初衷是为了重用string对象,节省内存 用代码实例验证下 public class StringInternTest { static f ...
- 字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化
字符串常量池也是运行时常量池 jdk1.6中,它是在方法区中,属于“永久代” jdk1.7中,它被移除方法区,放在java堆中 jdk1.8中,取消了“永久代”,将常量池放在元空间,与堆独立了 pub ...
- String intern()方法详解
执行以下代码 String a1=new String("abc"); String a2=new String("abc"); Sys ...
随机推荐
- WSL2 准备dotnet core开发环境
首先我们要知道WSL Ubuntu的版本,以便进行下一步操作: 我的是18.04,所以安装dot net SDK我们参考这里: https://docs.microsoft.com/en-us/dot ...
- Jenkins 持续集成测试工具
一.Jenkins(hudson)流程 创建job 执行job 通知机制 二.两种执行策略 定时执行:每隔一段时间执行一下(适合UI和接口测试的执行) 监控代码库执行:单元测试的执行模式(适合单元测试 ...
- Kubernetes安装EFK教程(非存储持久化方式部署)
1.简介 这里所指的EFK是指:ElasticSearch,Fluentd,Kibana ElasticSearch Elasticsearch是一个基于Apache Lucene的开源搜索和数据分析 ...
- Java中Class.forName()用法和newInstance()方法详解
1.Class.forName()主要功能 Class.forName(xxx.xx.xx)返回的是一个类, Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类,也就 ...
- React Gatsby 最新教程
React Gatsby 最新教程 https://www.gatsbyjs.com/docs/quick-start/ https://www.gatsbyjs.com/docs/tutorial/ ...
- webpack 性能优化 dll 分包
webpack 性能优化 dll 分包 html-webpack-externals-plugin DLLPlugin https://www.webpackjs.com/configuration/ ...
- Web 页面生命周期 All In One
Web 页面生命周期 All In One Web Page LifeCycle All In One refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允 ...
- Android四大组件简介:Android 基础知识,开发教程
Android 四大组件: Activity.Service.Broadcast Receiver.Content Provider. http://developer.android.com/int ...
- npm & cli & node.js
npm & cli & node.js https://www.npmjs.com/ https://www.npmjs.com/settings/xgqfrms/packages h ...
- Scalability & Scale-up & Scale-out
Scalability & Scale-up & Scale-out 架构,弹性,伸缩性 Scalability 可扩展性 https://en.wikipedia.org/wiki/ ...