String intern()的使用最全总结

intern的使用:
JDK1.8中:
判断这个常量是否存在于常量池。如果存在
判断存在内容是引用还是常量,
如果是引用,
返回引用地址指向堆空间对象,
如果是常量,
直接返回常量池常量
如果不存在,
将当前对象引用复制到常量池,并且返回的是当前对象的引用

public static void main(String[] args) {
    String s1 = new String("1");
    s1.intern();//这里之前已经将s1的常量放进去了,写不写都指向常量1
    String s2 = "1";
    System.out.println(s1 == s2);

    String s3 = new String("1") + new String("1");
    s3.intern();
    String s4 = "11";
    System.out.println(s3 == s4);
}

在JDK1.6下,StringPool在永久代,通过new关键字创建出来的有两个对象,一个在常量池,一个在堆中。
结果

false
false

在这里插入图片描述

JDK1.8下:
结果:

false
true

在这里插入图片描述
String a3 = new String(“1”) + new String(“1”);//只在堆上创建对象
S3.intern();//这里将s3的对象放进去了
String s4 = “11”;//这里查找到了,所以将s3的对象返回了,而不是返回常量
System.out.println(s3 == s4);//所以是true

  String s1 = new String("1");
    String s2 = "1";
    s1.intern();
    System.out.println(s1 == s2);

    String s3 = new String("1") + new String("1");
    String s4 = "11";
    s3.intern();
    System.out.println(s3 == s4);

JDK1.8下,s1与s2的地址不一致。s3创建好对象,但是s4在stringpool中创建常量,两个地址也是不一致。

所以返回false,false。

String str1 = "a";
String str2 = "b";
String str3 = "ab";
String str4 = str1 + str2;
String str5 = new String("ab");
 
System.out.println(str5.equals(str3));
System.out.println(str5 == str3);
System.out.println(str5.intern() == str3);
System.out.println(str5.intern() == str4);

得到的结果:

true
false
true
false

为什么会得到这样的一个结果呢?我们一步一步的分析。

第一、str5.equals(str3)这个结果为true,不用太多的解释,因为字符串的值的内容相同。
第二、str5 == str3对比的是引用的地址是否相同,由于str5采用new String方式定义的,所以地址引用一定不相等。所以结果为false。
第三、当str5调用intern的时候,会检查字符串池中是否含有该字符串。由于之前定义的str3已经进入字符串池中,所以会得到相同的引用。
第四,当str4 = str1 + str2后,str4的值也为”ab”,但是为什么这个结果会是false呢?先看下面代码:

String a = new String("ab");
String b = new String("ab");
String c = "ab";
String d = "a" + "b";
String e = "b";
String f = "a" + e;

System.out.println(b.intern() == a);
System.out.println(b.intern() == c);
System.out.println(b.intern() == d);
System.out.println(b.intern() == f);
System.out.println(b.intern() == a.intern());

运行结果:

false
true
true
false
true

由运行结果可以看出来,b.intern() == a和b.intern() == c可知,采用new 创建的字符串对象不进入字符串池,并且通过b.intern() == d和b.intern() == f可知,字符串相加的时候,都是静态字符串的结果会添加到字符串池,如果其中含有变量(如f中的e)则不会进入字符串池中。但是字符串一旦进入字符串池中,就会先查找池中有无此对象。如果有此对象,则让对象引用指向此对象。如果无此对象,则先创建此对象,再让对象引用指向此对象。

三.总结
1.只在常量池上创建常量

 String a1 = "AA";

2.只在堆上创建对象

 String a2 = new String("A") + new String("A");

3.在堆上创建对象,在常量池上创建常量

  String a4 = new String("A") + new String("A");//只在堆上创建对象AA
    a4.intern();//将该对象AA的引用保存到常量池上

4.在堆上创建对象,在常量池上创建引用, 在常量池上创建常量(不可能)

String a5 = new String("A") + new String("A");//只在堆上创建对象
    a5.intern();//在常量池上创建引用
    String a6 = "AA";//此时不会再在常量池上创建常量AA,而是将a5的引用返回给a6
    System.out.println(a5 == a6); //true
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,Stringintern()方法是用来将字符串添加到字符串常量池中并返回它的引用。当调用intern()方法时,如果字符串常量池中已经存在该字符串,则返回常量池中的引用;如果字符串常量池中不存在该字符串,则将该字符串添加到常量池中并返回新添加的引用。 例如,引用中的代码段中,当执行s2=s1.intern()时,会将s1的内容添加到字符串常量池中并返回其引用。因此,s2与s均指向字符串常量池中的同一个对象,所以s2==s的结果为true。而s1与s并不相等,因为s1是通过new关键字在堆中创建的新的String对象,而s是字符串常量池中的对象。 总结起来,使用intern()方法可以在字符串常量池中查找或添加字符串,并返回字符串常量池中的引用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Stringintern()方法浅析](https://blog.csdn.net/tianyuzui6/article/details/124417267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [详解Stringintern方法](https://blog.csdn.net/m0_59181747/article/details/121146280)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值