StringBuffer何时初始化到常量池

  • 首先,在源代码中用双引号引起来的会自动进入常量池中(其实字符串对象是在堆中,然后常量池里有个引用指向它,但是和直接说在常量池中似乎没多大影响,下面也就这么说了)
	String s1 = new StringBuffer("he").append("llo").toString();
	System.out.println(s1==s1.intern());//结果是true

这个he和llo都去池子里面了。

  • 然后,intern()方法在JDK1.7做了一点小改进,之前的做法是如果字符串是首次出现,那么将字符串复制到常量池中,然后返回常量池中的引用;JDK1.7的做法是如果是首次出现,那么在常量池中记下这个字符串的位置,然后直接返回这个引用。我这点儿语文我自己都觉得稀烂。。。。
jdk1.6和jdk1.7下intern()方法的区别
随便百度找的,基本就是《深入理解Java虚拟机》原文了。
文中说到"java"这个字符串并不是首次出现,它在这里:
<img src="https://i-blog.csdnimg.cn/blog_migrate/b672205bb055576e1c0234bab221249f.png" data-rawwidth="532" data-rawheight="127" class="origin_image zh-lightbox-thumb" width="532" data-original="https://pic1.zhimg.com/v2-ce0ed85448ce4d79824c61d9e4705074_r.png">在Oracle官网下载的JDK中rt.jar下可以找到这个类。当然如果你使用的是其他的JDK的话,可能并不是这样子哦,比如我手里这个JDK它是这样的:
在Oracle官网下载的JDK中rt.jar下可以找到这个类。当然如果你使用的是其他的JDK的话,可能并不是这样子哦,比如我手里这个JDK它是这样的:
<img src="https://i-blog.csdnimg.cn/blog_migrate/0ea23d6139be9517a8ffa82082d1166d.png" data-rawwidth="575" data-rawheight="128" class="origin_image zh-lightbox-thumb" width="575" data-original="https://pic1.zhimg.com/v2-9c328996c81cf72305752aa69e30a45c_r.png">所以用我手里这个去跑结果是这面这样子的:
所以用我手里这个去跑结果是这面这样子的:
<img src="https://i-blog.csdnimg.cn/blog_migrate/28b393e3565af8112bfe66fa5ae87bec.png" data-rawwidth="700" data-rawheight="145" class="origin_image zh-lightbox-thumb" width="700" data-original="https://pic3.zhimg.com/v2-13973bbcd75e35af7ce54fdfbcbe6296_r.png">
  • 解释一下题主给的代码的输出
	String s2 = new StringBuffer("word").toString();
	System.out.println(s2==s2.intern());//结果是false
"word"在常量池中,s2肯定是指向的堆中的某块地方,s2.intern()得到的是常量池中的,不是同一个,所以是false
	String s1 = new StringBuffer("he").append("llo").toString();
	System.out.println(s1==s1.intern());//结果是true

append一下和上面的区别在于,一开始"hello"并没有在常量池中,在池中的是"he"和"llo",再结合上面关于intern()方法的介绍,应该很好理解吧。(测试这种东西最好用一些乱七八糟的东西甚至是中文,比如上面的"java",其他地方已经出现过了,指不定什么地方也出现了"Hello")




StringBuffer的toString方法会调用new String, 在堆中新建对象。
 public synchronized String toString() {
        return new String(value, 0, count);
 }

String s2 = new StringBuffer("word").toString();
System.out.println(s2==s2.intern());//结果是false

1、word已经在字符串常量池中。
2、经过StringBuffer的toString以后,s2指向堆中新创建的对象。
3、s2.intern()拿到的是常量池中之前就存在的对象引用。
所以s2和s2.intern持有的不是同一个对象引用。

String s1 = new StringBuffer("he").append("llo").toString();
System.out.println(s1==s1.intern());//结果是true
1、hello不在字符串常量池中。
2、经过StringBuffer的toString以后,s1指向堆中新创建的对象,同时这个对象也被保存到常量池中。
3、s1.intern()去常量池中拿到的对象引用也正是刚刚新建的对象。
所以s1和s1.intern持有的是同一个对象引用。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值