解析1.8字符串常量池和String相加在字符串常量池的变化

字符串常量池
常量池存放字面量和符号引用,或者直接引用

intern方法,它的 作用 是 如果 字符串 常量 池 中 已经 包含 一个 等于 此 String 对象 的 字符串, 则 返回 代表 池 中 这个 字符串 的 String 对象 的 引用; 否则, 会 将此 String 对象 包含 的 字符串 添加 到 常量 池 中, 并且 返回 此 String 对象 的 引用。也就是说常量池里还是字面量

String b;
String a=new String(b="ss");
String intern = a.intern();
//true
System.out.println(b==intern);
//false
System.out.println(a==intern);

其实看这段代码就明白了,new String创建了俩个堆对象,看string那个String参数的构造方法上就已经写明了,就是复制那个string参数再弄一份副本,所以其实"ss"这个字面量已经进入常量池了,而常量池里就是第一次创建的堆对象的引用,而后面new,也就是再New一份实例出来了而已,

String str1 = new StringBuilder("计算机"). append("软件"). toString(); 
System. out. println( str1. intern() == str1); 
String str2 = new StringBuilder("ja"). append("va"). toString(); 
System. out. println( str2. intern() == str2); 

这段 代码 在 JDK 6 中 运行, 会 得到 两个 false, 而在 JDK 7 中 运行, 会 得到 一个 true 和 一个 false。 产生 差异 的 原因 是, 在 JDK 6 中, intern() 方法 会把 首次 遇到 的 字符串 实例 复制 到 永久 代 的 字符串 常量 池 中 存储, 返回 的 也是 永久 代 里面 这个 字符串 实例 的 引用, 而由 StringBuilder 创建 的 字符串 对象 实例 在 Java 堆 上, 所以 必然 不可能 是 同一个 引用, 结果 将 返回 false。 而 JDK 7( 以及 部分 其他 虚拟 机, 例如 JRockit) 的 intern() 方法 实现 就不 需要 再 拷贝 字符串 的 实例 到 永久 代 了, 既然 字符串 常量 池 已经 移到 Java 堆 中, 那 只需 要在 常量 池 里 记录 一下 首次 出现 的 实例 引用 即可, 因此 intern()返回 的 引用 和 由 StringBuilder 创建 的 那个 字符串 实例 就是 同一个。 而对 str2 比较 返回 false, 这是 因为“ java”这个 字符 串在 执行 StringBuilder. toString() 之前 就 已经 在加载 sun. misc. Version 这个 类 的 时候 进入 常量 池 的。所以 字符串 常量 池 中 已经 有 它的 引用, 不符合 intern() 方法 要求“ 首次 遇到” 的 原则,“ 计算机 软件” 这个 字符串 则是 首次 出现 的, 因此 结果 返回 true。

字面量相加
String a=“1”+“2”+“3”+“4”;
会被编译器优化为一个String a="1234"直接放入字符串常量池中

字符串相加
String b=new String(“he”)+new String(“llo”);
其实是使用的StringBuilder.append最后再toString,但是toString不会放入字符串变量池,如果再调用b.intern()才会放入此对象放入字符串常量池中,然后就会发现,字符串常量池里就是存放的b的引用地址

String b=new String("he")+new String("llo");
String bIntern = b.intern();
String b1="hello";
//true
System.out.println(b==bIntern);
//true
System.out.println(bIntern==b1);
//true
System.out.println(b==b1);

b1就是直接拿的b放入字符串常量池的那个对象

只是个人的一些想法,欢迎大家指正

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值