字符串常量池和intern()方法

一、Java中两种创建字符串对象的方式

public static void main(String[] args) {
        //使用字面值创建s1对象,对象实例存放于常量池;
        String s1 = "1";
        //使用new关键字创建s2对象,对象实例存放于堆中;
        String s2 = new String("1");
    }

s1对象创建过程解析:把字符串直接量的值传入常量池中,并把常量池中s1实例对象的地址返回给s1对象;

s2对象创建过程解析:在常量池中查找是否有s1对象的值。若有,则在堆中创建s2实例,并返回s2实例在堆中的地址;若无,则先在常量池中创建s2对象的值,之后在堆中创建s2对象的实例,并返回s2对象实例的地址;

为上述的内容验证代码如下

String s1 = "abc";
String s2 = "abc";
System.out.println(s1==s2);
//输出的结果是true表示在常量池中地址相等;
String s3 = new String("xyz");
String s4 = new String("xyz");
System.out.println(s3==s4);
//输出false,表示在堆中的地址不同

二、intern()方法的调用;

如果在常量池中有字符串的值,则把常量池中字符串的地址返回;

如果常量池中没有字符串的值,则在堆中查找。若有,则返回堆中的地址,并且把堆中的地址引用到常量池中;

如果常量池和堆中都没有,则将当前字符串复制到字符串常量池中,并返回字符串常量池中的引用;

String s1 = 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);

输出结果为 false true

String s1 = new String(“1”); 在字符串常量池中创建"1"对象,在堆中创建s对象。
s.intern(); 由于字符串常量池中已经有"1"对象,因此该句并无实际意义。
s2指向字符串常量池中"1"对象。
因此s指向堆中的引用,s2指向字符串常量池中的引用,返回 false。

s3.intern(); 先在字符串常量池中查找是否存在"11",再从堆中查找,然后将堆中s3的引用存储到字符串常量池中。
String s4 = “11”; 创建的时候发现字符串常量池中有了“11”(s3),然后指向s3引用的对象。
因此s3与s4的引用相同,返回 true。

三、JDK6和JDK7的不同

JDK6的常量池在"永久代"中,JDK7的常量池在堆中;

JDK6中只能查询或创建在字符串常量池;
JDK7中会先查询字符串常量池,若没有又会到堆中再去查询并存储堆的引用,然后返回;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值