java的string的intern_java String的intern()方法

intern()方法用于将字符串对象加入常量池中。

public native String intern();

intern()方法返回的是一个常量池中的String对象(即常量池中某个String对象的引用)。

String s = new String("1");

s.intern();

s是一个位于堆中的String对象,其字符串值为 "1" , 调用s的intern()方法,可在常量池中创建一个字符串值与s相同的String对象。

创建过程为:

首先查找常量池中是否已存在值为 "1" 的String对象,若存在则返回该对象。

若不存在,在JDK1.6及之前,会在常量池中创建一个新的值为 "1" 的String对象,并返回该对象。

在JDK1.7及之后,会将s的引用添加至常量池中,堆中的String对象s间接的成为了常量池中的一员,此时返回的是对象s。

示例:

public static voidmain(String[] args) {

String s= new String("1");

s.intern();

String s2= "1";

System.out.println(s==s2);

String s3= new String("1") + new String("1");

s3.intern();

String s4= "11";

System.out.println(s3==s4);}

jdk1.6下输出结果为 false  false

jdk1.7下输出结果为 false  true

jdk1.6下解释:

jdk6中的常量池是放在 Perm 区中的,Perm区和正常的 JAVA Heap 区域是完全分开的。使用引号声明的字符串都是会直接在字符串常量池中生成,而 new 出来的 String 对象是放在 JAVA Heap 区域。

String s = new String("1"); 创建了两个String对象,一个位于堆中即是s,一个位于常量池中,值为"1"。

String s2 = "1"; 由于常量池中已经存在值为"1"的String对象,所以s2指向的是常量池中的String对象。

所以s == s2 结果为false,s与s2指向的并不是同一个对象。

String s3 = new String("1") + new String("1"); 在堆中创建了一个值为"11"的String对象即是s3。

s3.intern();由于常量池中没有值为"11"的String对象,所以在池中创建了一个。

String s4 = "11";常量池中已经存在值为"11"的String对象,所以s4指向了常量池中的String对象。

所以s3 == s4 结果为false,s3与s4指向的并不是同一个对象。

97e4af6537517e82bce979ca67fc93b2.png

jdk1.7下解释:

String s = new String("1");

s.intern();

String s2= "1";

System.out.println(s==s2);

String s3= new String("1") + new String("1");

s3.intern();

String s4= "11";

System.out.println(s3==s4);

System.out.println(s3.intern()== s3);

在 jdk7 及以后的版本中,字符串常量池从Perm区移到Java Heap区域。

String s = new String("1"); 创建了两个String对象,一个位于堆中即是s,一个位于常量池中,值为"1"。

String s2 = "1"; 由于常量池中已经存在值为"1"的String对象,所以s2指向的是常量池中的String对象。

所以s == s2 结果为false,s与s2指向的并不是同一个对象。

String s3 = new String("1") + new String("1"); 在堆中创建了一个值为"11"的String对象即是s3。

s3.intern();由于常量池中没有值为"11"的String对象,所以在常量池中添加对象s3的引用。

String s4 = "11";常量池中已经存在值为"11"的String对象(这个对象实际是s3),所以s4指向了s3指向的String对象。

所以s3 == s4 结果为true,s3与s4指向的是同一个对象,都是堆中值为 "11" 的String对象。

061217a7fc9d4fc2f1c3967f6bd9906b.png

其它示例:

//在堆中创建了一个值为"11"的String对象即是s3

String s3 = new String("1") + new String("1");//常量池中没有值为"11"的String对象//所以在池中创建了一个新的String对象

String s4 = "11";//常量池中存在值为"11"的String对象,即是s4指向的对象//intern返回s4指向的对象

s3.intern();//intern返回的是s4指向的对象

System.out.println(s3.intern() == s4); //true//s3指向的是堆中的对象//s4指向的是常量池中新建的对象//故结果为false

System.out.println(s3 == s4); //false

String str1 = new String("Hello") + new String("World");

System.out.println(str1.intern()== str1); //true

String str2 = "HelloWorld";

System.out.println(str1== str2); //true

String str2 = "HelloWorld";

String str1= new String("Hello") + new String("World");

System.out.println(str1.intern()== str1); //false

System.out.println(str1 == str2); //false

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值