解析String.intern()

解析String.intern()JAVAString

大家好,欢迎来到IT知识分享网。


前言

在 JAVA 语言中有8中基本类型和一种比较特殊的类型String。这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念。常量池就类似一个JAVA系统级别提供的缓存。
String类型的常量池主要使用方法有以下两种(基于JDK7以后的版本)

  • 直接使用双引号声明的String对象会直接存储在常量池中。例如:String str="abc";该语句对在创建常量池中创建一个”abc”字符串对象。
  • 如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。例如:
/* 执行该语句会在字符串常量池中创建对象"abc"和"123",已及JAVA Heap中str引用指向的对象 (还有两个匿名对象new String("abc")、new String("123"),先不做讨论)。 此时str引用的对象内容为"abc123",但此时常量池中没有"abc123"这个对象。 */ String str=new String("abc")+String("123"); /*执行str.interm();语句是将str中的"abc123"字符串放入 String 常量池中,因为此时常量池中不存在“abc123”字符串*/ str.interm(); 

通过两段代码进一步理解interm()方法

/*代码段1*/ public static void main(String[] args) { 
    String s1 = new String("a"); s1.intern(); String s2 = "a"; System.out.println(s1 == s2); String s3 = new String("b") + new String("b"); s3.intern(); String s4 = "bb"; System.out.println(s3 == s4); } 

输出结果为:

false true 

在这里插入图片描述

  • 我们看语句String s1 = new String("a");,生成了常量池中创建”a”和Java Heap中的字符串对象,s1.intern(); 这一句是 s1 对象去常量池中寻找后发现 “a” 已经在常量池里了。
  • 接下来String s2 = "a"; 这句代码是生成一个 s2的引用直接指向常量池中的“a”对象。 结果就是 s 和 s2 的引用地址明显不同。所以输出false
  • s3和s4字符串。String s3 = new String("b") + new String("b");,这句代码中现在生成了2最终个对象,是字符串常量池中的“b” 和 JAVA Heap 中的 s3引用指向的对象。中间还有2个匿名的new String("b")我们不去讨论。此时s3引用对象内容是”bb”,但此时常量池中是没有 “bb”对象的。
  • 接下来s3.intern();这一句代码,是将 s3中的“bb”字符串放入 String 常量池中,因为此时常量池中不存在“bb”字符串,所以在常量池中生成一个 “bb” 的对象,关键点是常量池也在 Java Heap区域,常量池中不需要再存储一份对象了,可以直接存储堆中的引用。这份引用指向 s3 引用的对象。 也就是说引用地址是相同的。因此输出true
/*代码段2*/ public static void main(String[] args) { 
    String s1 = new String("a"); String s2 = "a"; s1.intern(); System.out.println(s1 == s2); String s3 = new String("b") + new String("b"); String s4 = "bb"; s3.intern(); System.out.println(s3 == s4); } 
false false 

在这里插入图片描述

  • s 1和 s2 代码中,s1.intern();,这一句往后放也不会有什么影响了,因为对象池中在执行第一句代码String s1= new String("a");的时候已经生成“a”对象了。下边的s2声明都是直接从常量池中取地址引用的。 s1 和 s2 的引用地址是不会相等的。
  • 执行String s4 = "bb";声明 s4 的时候常量池中是不存在“bb”对象的,执行完毕后,“bb“对象是 s4 声明产生的新对象。然后再执行s3.intern();时,常量池中“bb”对象已经存在了,因此 s3 和 s4 的引用是不同的。所以俩比较均输出fales

总结

在JDK7后String.intern() 方法时,如果存在堆中的对象,会直接保存对象的引用,而不会重新创建对象。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/153469.html

(0)
上一篇 2025-03-03 19:45
下一篇 2025-03-03 20:05

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信