【无标题】

**

intern()方法

**

(一)new String在常量池中生成字符串,在堆上创建字符串对象。

String s = newString("1"),生成了常量池中的“1” 和堆空间中的字符串对象。
s.intern();

当调用intern()方法时,s对象去常量池中寻找后发现"1"已经存在于常量池中了(s的引用地址是堆中指向常量池)。

(二)通过字面赋值创建字符串

String s2 = "1",这行代码是生成一个s2的引用指向常量池中的“1”对象。

先在常量池中查找是否存在,若存在,则将栈中的引用直接指向该字符串;若不存在,则会在常量池中生成一个字符串,再将栈中的引用直接指向该字符串。

举例1

String s = new String("1");
s.intern();
String s2 = "1";
System.out.println(s == s2);
输出:false 原因: s 和 s2 的引用地址明显不同。因此返回了false

举例2

String s3 = new String("1") + new String("1");
//在字符串常量池中生成“1” ,并在堆空间中生成s3引用指向的对象
//(内容为"11")。注意此时常量池中是没有 “11”对象的
s3.intern();
//将s3中的“11”字符串放入 String常量池中,此时常量池中
//不存在“11”字符串
//JDK1.6的做法是直接在常量池中生成一个 "11" 的对象
//JDK1.7直接存储堆中的引用。
//这份引用直接指向 s3 引用的对象,
//也就是说s3.intern() == s3会返回true。
String s4 = "11";
System.out.println(s3 == s4);
输出:JDK1.6及以下:fasle
     JDK1.7及以上:true

(三)常量字符的 “+” 操作,会直接在编译阶段,将字符串合并,如:
String = ‘‘str11’’ + "333’’, 在编译阶段会直接将字符串合并为String = ‘‘str11333’’,于是会去常量池中查找是否存在’‘str11333’’,从而进行创建或者引用。

(四)对于final字段,编译器直接进行了常量替换,
(非final字段,则进行了赋值)
final String str1 = ‘‘ja’’;
final String str2 = ‘‘va’’;
String str3 = str1 + str2;
在编译时,直接替换成了String str3=”ja”+”va”,
根据第三条规则,再次替换成String str3=”JAVA”

(五)常量字符串和变量拼接时(如:String str3=baseStr + “01”;)
会调用stringBuilder.append()在堆上创建新的对象

(六)JDK 1.7后,intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中字符串的引用,这一点与之前没有区别:

区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。

简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。

在这里插入图片描述
举例3:

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

String s = newString(“1”),生成了常量池中的“1” 和堆空间中的字符串对象。

String s2 = “1”,这行代码是生成一个s2的引用指向常量池中的“1”对象,但是发现已经存在了,那么就直接指向了它。

s.intern(),这一行在这里就没什么实际作用了。因为"1"已经存在了。

结果就是 s 和 s2 的引用地址明显不同。因此返回了false

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

String s3 = new String(“1”) + newString(“1”),这行代码在字符串常量池中生成“1” ,并在堆空间中生成s3引用指向的对象(内容为"11")。注意此时常量池中是没有 “11”对象的。

String s4 = “11”, 这一行代码会直接去生成常量池中的"11"。

s3.intern(),这一行在这里就没什么实际作用了。因为"11"已经存在了。

结果就是 s3 和 s4 的引用地址明显不同。因此返回了false

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值