Java编译器对String的优化

来源:互联网 发布:中韩贸易数据 编辑:程序博客网 时间:2024/05/01 17:57

首先看以下的代码:

public static void main(String[] arge) {        //1        String str1 = new String("1234");        String str2 = new String("1234");        System.out.println("new String()==:" + (str1 == str2));        //2        String str3 = "1234";        String str4 = "1234";        System.out.println("常量字符串==:" + (str3 == str4));        //3        String str5 = "1234";        String str6 = "12" + "34";        System.out.println("常量表达式==:" + (str5 == str6));        //4        String str7 = "1234";        String str8 = "12" + 34;        System.out.println("字符串和数字相加的表达式==:" + (str7 == str8));        //5        String str9 = "12true";        String str10 = "12" + true;        System.out.println("字符串和Boolen相加表达式==:" + (str9 == str10));        //6        final String val = "34";        String str11 = "1234";        String str12 = "12" + val;        System.out.println("字符串和常量相加的表达式==:" + (str11 == str12));        //7        String str13 = "1234";        String str14 = "12" + getVal();        System.out.println("字符串和函数得来的常量相加表达式==:" + (str13 == str14));    }    private static String getVal()    {        return "34";    }

运行输出:

new String()==:false
常量字符串==:true
常量表达式==:true
字符串和数字相加的表达式==:true
字符串和Boolen相加表达式==:true
字符串和常量相加的表达式==:true
字符串和函数得来的常量相加表达式==:false

代码分析:

Java中,String是引用类型;==是关系运算符,==比较两个引用类型时,判断的依据是:双方是否是指向了同一个内存地址。

(1)String为引用类型,str1和str2为新实例化出来的对象,分别指向不同的内存地址。而==对于引用类型判断,是判断的是引用地址,所以例子1结果为false。

(2)对于第二个例子,编译器编译代码时,会将”1234”当做一个常量,并保存在JVM的常量池中,然后编译String str3=”1234”;时,将常量的指针赋值给str3,在编译String str4=”1234”;时,编译器查找常量池里有没有值相同的常量,如果有就将存在的常量赋给str4,这样结果就是str3和str4都指向了常量池中的常量的地址,所以==比较结果为true;

(3)第三个例子,编译时编译器发现能够计算出”12”+”34”的值,它是个常量,就按照第二个例子一样处理,最终str5和str6都指向了同一个内存地址。所以==比较结果为true;

(4)第四个例子、第五个例子和第六个例子,类似第三个例子,编译时编译器发现能够计算出值,就尽量计算出来,所以==比较结果为true;

(5)第七个例子中,编译器发现str14值是要调用函数才能计算出来的,是要在运行时才能确定结果的,所以编译器就设置为运行时执行到String str14=”12” + getVal();时 要重新分配内存空间,导致str13和str1是指向两个不同的内存地址,所以==比较结果为false;

原创粉丝点击