String.intern()的用法
String.intern()官方给的定义:
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
实际上,就是去拿String的内容去Stringtable里查表,如果存在,则返回引用,不存在,就把该对象的"引用"存在Stringtable表里。
public class RuntimeConstantPoolOOM{public static void main(String[] args) {String str1 = new StringBuilder("计算机").append("软件").toString();System.out.println(str1.intern() == str1);String str = "java";String str2 = new StringBuilder("ja").append("va").toString();System.out.println(str2.intern() == str2);}
}
以上代码,在 JDK6 下执行结果为 false、false,在 JDK7 以上执行结果为 true、false。
首先我们调用StringBuilder创建了一个"计算机软件"String对象,因为调用了new关键字,因此是在运行时创建,之前JVM中是没有这个字符串的。
在 JDK6 下,intern()会把首次遇到的字符串实例复制到永久代中,返回的也是这个永久代中字符串实例的引用;而在JDK1.7开始,intern()方法不再复制字符串实例,String 的 intern 方法首先将尝试在常量池中查找该对象的引用,如果找到则直接返回该对象在常量池中的引用地址。
因此在1.7中,“计算机软件”这个字符串实例只存在一份,存在于java堆中!我们知道当String str1 = new StringBuilder(“计算机”).append(“软件”).toString();这句代码执行完之后,已经在堆中创建了一个字符串对象,那么str1.intern()会将该字符串对象尝试放入到串池中,这当然满足str1.intern() == str1——都是他自己嘛;对于引用str2,因为JVM中已经有“java”这个字符串了,因此new StringBuilder(“ja”).append(“va”).toString()会重新创建一个新的“java”字符串对象,而intern()会返回首次遇到的常量的实例引用,因此他返回的是系统中的那个"java"字符串对象引用(首次),因此会返回false。
在 JDK6 下 str1、str2 指向的是新创建的对象,该对象将在 Java Heap 中创建,所以 str1、str2 指向的是 Java Heap 中的内存地址;调用字符串对象的intern方法,会将该字符串对象尝试放入到串池中。如果串池中没有该字符串对象,会将该字符串对象复制一份,再放入到串池中。如果有该字符串对象,则放入失败。所以此时 str1/str2.intern() 指向的是常量池中的地址。
总结
可以使用intern方法,主动将串池中还没有的字符串对象放入串池中
intern方法 1.8
调用字符串对象的intern方法,会将该字符串对象尝试放入到串池中
- 如果串池中没有该字符串对象,则放入成功
- 如果有该字符串对象,则放入失败
无论放入是否成功,都会返回串池中的字符串对象
注意:此时如果调用intern方法成功,堆内存与串池中的字符串对象是同一个对象;如果失败,则不是同一个对象
intern方法 1.6
调用字符串对象的intern方法,会将该字符串对象尝试放入到串池中
- 如果串池中没有该字符串对象,会将该字符串对象复制一份,再放入到串池中
- 如果有该字符串对象,则放入失败
无论放入是否成功,都会返回串池中的字符串对象
注意:此时无论调用intern方法成功与否,串池中的字符串对象和堆内存中的字符串对象都不是同一个对象
对于程序中大量使用存在的字符串时,尤其存在很多已经重复的字符串时,使用intern()方法能够节省内存空间。
大的网站平台,需要内存中存储大量的字符串。比如社交网站,很多人都存储:北京市、海淀区等信息。这时候如果字符串都调用intern() 方法,就会很明显降低内存的大小。
String.intern()的用法相关推荐
- String,intern()有关的那点事儿
String,是Java中除了基本数据类型以外,最为重要的一个类型了.很多人会认为他比较简单.但是和String有关的面试题有很多,下面我随便找两道面试题,看看你能不能都答对: Q1:String s ...
- string类具体用法
string类具体用法 二话不说上代码 #include<string> #include<iostream> #include<algorithm> using ...
- String.intern()方法JDK6与JDK7/JDK8不同
在JDK6中,String.intern()方法先去运行时常量池中查看有无该字符串,如果有,则直接返回该字符串在方法区的内存地址.如果没有则会先将该字符串对象复制一份保存在常量池中,并返回该字符串对象 ...
- string和stringstream用法总结
string和stringstream用法总结 一.string string 是 C++ 提供的字串型態,和 C 的字串相比,除了有不限长度的优点外,还有其他许多方便的功能.要使用 string, ...
- 深入解析String#intern
为什么80%的码农都做不了架构师?>>> 引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了 ...
- 使用String.intern减少内存使用
最近写一个程序,从文件中读取一些字/词,然后存储起来供别的类引用. 对每个读入的词创建一个String,结果许多同样内容的也会存储多份,会占用大量内存. 开始的一个想法是使用map/set来存储所有遇 ...
- 01.几张图轻松理解String.intern()
当调用 intern() 方法时,编译器会将字符串添加到方法区的运行常量池中(stringTable维护),并返回指向该常量的引用. 在翻<深入理解Java虚拟机>的书时,又看到了2-7的 ...
- string的常见用法详解
目录 string的定义 string中内容的访问 string常用函数实例解析 在C语言中,一般使用字符数组char str[]来存放字符串,但是使用字符数组有时会显得操作麻烦,而且容易因经验不足而 ...
- Java基础提升篇:理解String 及 String.intern() 在实际中的应用
点击上方"好好学java",选择"置顶公众号" 优秀学习资源.干货第一时间送达! 好好学java java知识分享/学习资源免费分享 关注 精彩内容 你所需要的 ...
最新文章
- Google推出的新服务:Docs Spreadsheets
- 常见的面试题(整理)
- 并发基础(七):Thread 类的sleep()、yeild()、join()
- [转][Java]尝试解决Java多行字符串的编辑问题
- 练习7-11 字符串逆序 (15分)
- 【SpringBoot实战】员工部门管理页面,增删改查,含源码
- 记一次偶遇Adminer
- @Override must override a superclass method
- 最简单快捷搭建私链步骤笔记
- Android WebView 加载超长 JS 数据
- Web漏洞总结: OWASP Top 10
- 中级计算机网络管理员试卷,计算机网络管理员中级考试题及答案
- android打开系统文件怎么打开方式,Android调用系统应用打开任意文件
- 对Java语言入门初学者的一些建议
- python中各种序列/容器的索引、切片小结;如何取得可迭代对象中的element?如何取元素?
- Linux_cJSON--数据封装与解析
- 3c认证是什么,3c认证产品范围与认证材料
- Linux安装pyhive
- 【毕业设计】基于SSM的酒店客房信息管理系统 - java web
- Revit结构构件之间的扣减问题及解决