在Java编程中,字符串是最常用的数据类型之一,但是对于字符串的操作往往需要注意内存的使用和性能问题。本文我们将深入探讨Java中的字符串优化技术,重点关注于String类的intern()方法,以及如何正确地使用它来优化字符串操作
今日内容介绍,大约花费9分钟
图片
昨天介绍了深入理解Java字符串常量池,介绍了String创建方法以及字符串常量池,今天介绍String一个方法String.intern(),大家可以看看美团写的美团技术团队深入解析 String.intern()文章,这是精品中精品,可是大家看了之后会觉得,我要放弃学习Java,因为有点看不懂,那么我简化给大家讲讲,前提是小伙伴已经理解昨天深入理解Java字符串常量池这篇文章一下几点:
思考:new String("spring") + new String("葵花宝典");操作如何进行性能优化
String str = new String("spring") + new String("葵花宝典");
如果要把上面str内容存放到常量池,就需要使用intern()方法
注意:Java 7时,字符串常量池从永久代中移动到了堆中,但是永久代还没有完全被移除。Java 8时,永久代被彻底移除。
Java 7之前和Java 7之后,String.intern()方法在执行时的策略发生了变化,这一变化直接影响了内存的利用方式
可能小伙伴还没有理解,那么别怕,通过以下例子进行说明
String str1 = new String("spring葵花宝典");
String str2= str1.intern();
System.out.println(str1 == str2);
思考:大家猜猜上面代码结果是什么?可能小伙伴猜不出来,那么我直接来解释一下
第一行,字符串常量池中会先创建一个spring葵花宝典的对象,然后堆中会再创建一个spring葵花宝典的对象,str1 引用的是堆中的对象。
第二行,str1 执行 intern() 方法,该方法会从字符串常量池中查找spring葵花宝典,如果常量池中存在spring葵花宝典字符串是否存在,因为第一行代码已经在字符串常量池创建spring葵花宝典,所以 str2引用的是字符串常量池中的对象
图片
image
str1 和 str2 的引用地址是不同的,str1一个来自堆,str2一个来自字符串常量池,所以输出的结果为 false。
String str1 = new String("spring") + new String("葵花宝典");
String str2= str1.intern();
System.out.println(str1 == str2);
思考:2.1输出结果是false,那么2.2结果也是false?
可能小伙伴猜错了,代码输出结果为true,这是为啥?
第一行,字符串常量池中会先创建两个对象spring和葵花宝典,然后堆中会再创建两个匿名对象spring和葵花宝典,最后还有一个spring葵花宝典对象(一会解释),str1 引用的是堆中spring葵花宝典对象。
第二行,str1 执行 intern() 方法,该方法会从字符串常量池中查找spring葵花宝典对象是否存在,此时字符串常量池不存在,但是堆中存在
图片
image
字符串常量池中保存的是堆中spring葵花宝典对象的引用,也就是说,str1 和 str2 的引用地址是相同,所以输出的结果为 true
具体步骤如下:
特别说明:编译器遇到 + 号这个操作符的时候,会将 new String("spring") + new String("葵花宝典") 编译代码如下:
new StringBuilder().append("spring").append("葵花宝典").toString();
实际步骤如下:
尽管String.intern()方法能够有效地优化字符串操作,但是在使用时需要注意以下几点: