Java的String

1、生成字符串方式的区别

字符串不属于基本类型,但是可以像基本类型一样,直接通过字面量赋值,当然也可以通过new来生成一个字符串对象。不过通过字面量赋值的方式和new的方式生成字符串有本质的区别:

字符串11.1、通过字面量赋值创建字符串时,会优先在常量池中查找是否已经存在相同的字符串,倘若已经存在,栈中的引用直接指向该字符串;
倘若不存在,则在常量池中生成一个字符串,再将栈中的引用指向该字符串。

1.2、而通过new的方式创建字符串时,就直接在堆中生成一个字符串的对象,栈中的引用指向该对象。(备注,JDK 7 以后,HotSpot 已将常量池从永久代转移到了堆中)

1.3、对于堆中的字符串对象,可以通过 intern() 方法来将字符串添加的常量池中,并返回指向该常量的引用。

2、一些骚操作

2.1、在JAVA 1.6之后,常量字符串的“+”操作,编译阶段直接会合成为一个字符串。

2.2、对于final字段,编译期直接进行了常量替换,而对于非final字段则是在运行期进行赋值处理的。

3、代码片段分析

3.1、代码段1

public class StringTest {
    public static void main(String[] args) {
        String str1 = "string";
        String str2 = new String("string");
        String str3 = str2.intern();
 
        System.out.println(str1==str2);//#1
        System.out.println(str1==str3);//#2
    }
}

3.2、代码段2

public class StringTest01 {
    public static void main(String[] args) {
        String baseStr = "baseStr";
        final String baseFinalStr = "baseStr";
 
        String str1 = "baseStr01";
        String str2 = "baseStr"+"01";
        String str3 = baseStr + "01";
        String str4 = baseFinalStr+"01";
        String str5 = new String("baseStr01").intern();
 
        System.out.println(str1 == str2);//#3
        System.out.println(str1 == str3);//#4
        System.out.println(str1 == str4);//#5
        System.out.println(str1 == str5);//#6
    }
}

3.3、代码段3-1

public class InternTest {
    public static void main(String[] args) {
 
        String str2 = new String("str")+new String("01");
        str2.intern();
        String str1 = "str01";
        System.out.println(str2==str1);//#7
    }
}

3.4、代码段3-2

public class InternTest01 {
    public static void main(String[] args) {
        String str1 = "str01";
        String str2 = new String("str")+new String("01");
        str2.intern();
        System.out.println(str2 == str1);//#8
    }
}

3.5、结果分析

结果 #1:因为str1指向的是字符串中的常量,str2是在堆中生成的对象,所以str1==str2返回false。

结果 #2:str2调用intern方法,会将str2中值(“string”)复制到常量池中,
但是常量池中已经存在该字符串(即str1指向的字符串),
所以直接返回该字符串的引用,因此str1==str2返回true。

结果#3:str1==str2 肯定会返回true,因为str1和str2都指向常量池中的同一引用地址。

结果 #4:因为str3实际上是stringBuilder.append()生成的结果,所以与str1不相等,结果返回false。

结果 #5 :因为str1和str4指向的都是常量池中的第三项,所以str1==str4返回true。

结果 #6 :因为str5和str1都指向的都是常量池中的同一个字符串,所以str1==str5返回true。

结果 #7:在第一种情况下,因为常量池中没有“str01”这个字符串,
所以会在常量池中生成一个对堆中的“str01”的引用,而在进行字面量赋值的时候,常量池中已经存在,
所以直接返回该引用即可,因此str1和str2都指向堆中的字符串,返回true。

结果 #8:调换位置以后,因为在进行字面量赋值(String str1 = "str01")的时候,常量池中不存在,
所以str1指向的常量池中的位置,而str2指向的是堆中的对象,再进行intern方法时,
对str1和str2已经没有影响了,所以返回false。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值