String邂逅字符串常量池

参考:String 字符串常量池

如何理解《深入理解java虚拟机》第二版中对String.intern()方法的讲解中所举的例子

一、新建了几个对象?

String str1 = "aaa";  //新建1个对象
String str2 = "bbb";  //新建1个对象
String str3 = "aaabbb";  //新建1个对象
  
String str4 = "aaa" + "bbb";//由于str3不会产生新的字符串对象  
System.out.println(str3 == str4);//true  
  
String str41 = str1 + "bbb";//会产生新的字符串对象,
System.out.println(str3 == str41);//false  
  
String str42 = str1 + str2;//会产生新的字符串对象  
System.out.println(str3 == str42);//false  

String str5 = new String(Str3); //产生新的字符串对象
String str6 = new String("aaabbb");//产生新的字符串对象

String str4 = "aaa" + "bbb" (如果没有前提str3) 只创建1个对象。由于常量字符串是在编译的时候就也被确定的,又因"aaa"和"bbb"都是常量,因此变量str的值在编译时就可以确定。

String str41 = str1 + "bbb"; //会产生新的字符串对象。 因为 “+ ”操作实际上是新建一个StringBuilder()并调用append()方法,生成了一个新对象。

二、String.intern()

String.intern()是一个本地方法,他的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回此String对象的引用;否则把此String对象的字符串拷贝到字符串常量池。

2.1 JDK不同版本中的intern()方法

JDK 6

JDK 7

三、字符串常量池在运行时数据区的位置

JDK 6以及以下,字符串常量池在方法区中,可以通过 -XX:PermSize-XX:MaxPermSize去设置方法区(永久代);

JDK 7或者更高版本的JDK ,字符串常量池在堆中。

如下代码,结果是什么?分析下,

public static void main(String[] args) {
    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
    false
#JDK 7 运行结果是:
    true
    false

JDK 6及以下中intern()方法会把字符串实例复制到永久代的字符串常量池中。而 JDK 7及以上版本中,因为字符串常量池在堆中,所以intern()方法仅仅把字符串实例引用放入字符串常量池中。

所以 JDK 6 执行 str1.intern() == str1 为 false , str1.intern() 返回的是永久代字符串常量池里面的对象引用,而str1返回的是堆中对象的引用。

JDK 7 执行 str1.intern() 返回的是字符串实例引用,和new StringBuilder(“计算机”)对象引用是同一个。

而 str2 的结果false, 是因为在执行new StringBuilder("ja").append("va").toString()之前,就已经存在了,它是加载sun.misc.Version这个类的时候就进入常量池的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值