不同JDK版本间intern()方法的区别——JDK6 VS JDK6+

String s = new String("a");
s.intern():

JDK6:当调用intern方法时,如果字符串常量池先前已创建出该字符串对象,则返回池中的该字符串的引用。否则,将此字符串对象添加到字符串常量池中,并且返回该字符串对象的引用。

JDK6+:当调用intern方法时,如果字符串常量池先前已创建出该字符串对象,则返回池中该字符串的引用。否则,如果该字符串对象已经存在于Java堆中,则将堆中对此对象的引用添加到字符串常量池中,并且返回该引用;如果堆中不存在,则在池中创建该字符串并返回其引用。

public class InternTest {

    public static void main(String[] args) {
        String s = new String("mogen");
        s.intern();
        String s1 = "mogen";
        System.out.println(s == s1);

        String s2 = new String("mogen") + new String("mogen");
        s2.intern();
        String s3 = "mogenmogen";
        System.out.println(s2 == s3);
    }
}

在编译器中运行InternTest.java代码

注:equals比较的是两个变量的值是否相同;==比较的是两个变量的地址是否相同

当是JDK6时,返回false和false;是将Java Heap堆里对象的副本放入到常量池中,原有对象与副本对象地址是不同的
当是JDK6+时,返回false和true;是将其引用放入到常量池中,则有可能地址相同

  1. String("mogen")声明一个对象时,将其放入到字符串常量池中;当new一个对象String s时,将其放置到Java Heap中;s.intern()欲将Java Heap中的s对象的副本"mogen"放一个到字符串常量池中去,但此时字符串常量池中已经有了前面声明的"mogen",所以s对象还是指向Java Heap中的对象(所以JDK6+时对象的引用也未放置成功);String s1 = "mogen"声明的对象s1则指向在字符串常量池中已有的"mogen"对象;s与s1分别指向java Heap和字符串常量池中的对象,所以结果返回false。(JDK6+因为已经存在)
  2. String("mogen")声明对象,字符串常量池中已经存在了“mogen”new一个对象String s2放置到Java Heap中("mogenmogen");s2.intern()欲将“mogenmogen”的副本放置到常量池中,因为此时常量池中没有,所以放置成功;但是因为放置的只是s2的副本,此时s2指向的还是Java Heap中的对象;s3="mogenmogen"声明后指向了字符串常量池中的对象;因此,s2与s3指向的对象地址不同,返回false。

JDK6+:区别在于此时放置的是Java Heap中对象的引用到字符串常量池中。第二种情况下放置的是s2的引用到常量池中,引用对象与原有对象地址相同,所以后续s2与s3的指向地址也就一致

:引号声明的对象都会放到永久代的字符串常量池中;new创建的对象都会放在Java Heap中

什么是值传递和引用传递?

  • 值传递是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量
  • 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本,并不是原对象本身。所以对引用对象进行操作会同时改变原对象
  • 一般认为,Java内的传递都是值传递

补充学习

Java intern()方法
浅谈String.intern()方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值