Java中字符串常量池的陷阱

public class TestCase
{
    static String ab = "ab";
    static String getA()
    {
        return "a";
    }
    static String getAB()
    {
        return "ab";
    }
    public static void main(String[] args)
    {
        // 1
        String _ab = new String("ab");
        System.out.printf("ab==_ab %b\n", ab==_ab);
        // 2
        String s1 = "a"+"b";
        System.out.printf("ab==s1 %b\n", ab==s1);
        // 3
        String s2 = getA()+"b";
        System.out.printf("ab==s2 %b\n", ab==s2);
        // 4
        System.out.printf("ab==getAB() %b\n", ab==getAB());
        // 5
        String s3 = new String("ab");
        System.out.printf("ab==s3 %b\n", ab==s3);
    }
}

输出结果:

ab==_ab false
ab==s1 true
ab==s2 false
ab==getAB() true
ab==s3 false

第一条输出:

虽然常量池里面有”ab”这个字符串, 但是_ab是内存中另外一个String对象的引用.

第二条输出:

编译器优化, 由于+左右都是显式的字符常量, 所以加号操作符没有申请新的String变量, 而是指向常量池中原有的”ab”. 如果常量池中并没有”ab”, 那么加号操作符就会在常量池中添加”ab”

第三条输出:

由于编译器认为左操作数是String而不是字符串常量(谁叫它不是显性的2333), 所以编译器不进行优化. 加号操作符将申请新String.

第四条输出:

由于ab和getAB()指向同一个字符串常量”ab”, 地址必然相同.

第五条输出:

好像跟第一条重复了233

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。