美文网首页zikmp
Java String直接赋值和new对象的相关问题

Java String直接赋值和new对象的相关问题

作者: 潇Lee | 来源:发表于2016-07-24 23:16 被阅读896次

    在Java语言中,String类型变量直接赋值和使用new方式新建String对象是完全不同的两种方式,产生的结果也不一样,需要了解其中的差别。

    概念:

    1. Java常量池
      类在加载完成之后,会在内存中存储类中的一些字面量(本身即是值如10,“abc”),对于字符串常量来说,Java会保证常量池中的字面量不会有多个副本,也就是说在常量池中的字符串不可能有两个字符串是相同的,但是Java代码中可能不同的变量的值是相同的,那么在编译期间,这两个变量值所在地址是相同的。而且Java在编译期间会对字符串进行一定的处理,如果一个字符串采用拼接的方式,并且拼接的内容都是字面量的话,那么会自动将字符串先拼接完再赋值,如果常量池中已经有了拼接完成之后的字面量,那么此变量的值的地址就是常量池中的完整字符串的地址。需要注意的是,String在赋值完成之后修改,是会产生新的变量的。比如:
    String str = "reeves";
    str = "abc";
    

    那么实际上在常量池中存储了"reeves"和"abc"两个字面值,在字符串变量赋予新的值的时候并不会改变原先存储的值,它会再新建一个字符串,而在栈中变量存储的值的地址是变了的。

    使用:

    例子1:

    String str1 = "reeves";
    String str2 = "reeves";
    System.out.println(str1==str2); // 结果:true
    

    例子中新建了两个变量str1和str2,值相同,在编译期间变量str1和str2值得地址都可以确定,因为两个变量的值相同,指向常量池中的地址也相同,因此使用“==”符号来判断两者值得地址是否相同时,返回的是true。

    例子2:

    String str1 = "reeves";
    String str2 = "ree"+"ves";
    System.out.println(str1==str2); // 结果:true
    

    Java语言在编译期间,对于字符串拼接且拼接元素都是字面量的情况,会自动将拼接字符串拼接完整之后再赋值,因此 String str2 = "ree"+"ves"; 就相当于 String str2 = "reeves"; 而“reeves”字面量在常量池中存在,因此str2的引用地址和str1相同。

    例子3:

    String str = new String("reeves");
    

    使用new关键字新建String对象时,会在堆中新创建一个字符串对象,值为“reeves”,同时,Java也会监测常量池中是否有“reeves”字面量,如果没有,那么在常量池中再新建一个“reeves”的字面量。

    例子4:

    String str1 = "reeves";
    String str2 = str1.intern();
    System.out.println(str1==str2); //结果:true
    

    String的intern()方法会监测常量池中是否有该字符串的值的字面量,如果有,返回字面量的地址,如果没有,则新建字面量并返回新建字面量的地址。

    相关文章

      网友评论

        本文标题:Java String直接赋值和new对象的相关问题

        本文链接:https://www.haomeiwen.com/subject/tqhwjttx.html