美文网首页
java关于String的编译优化

java关于String的编译优化

作者: CarsonCao | 来源:发表于2019-11-10 22:01 被阅读0次
       public static String getA() {
            return "a";
        }
    
        public static void main(String[] args) {
            String a = "a";
            final String c = "a";
    
            String b = a + "b";
            String d = c + "b";
            String e = getA() + "b";
    
            String compare = "ab";
    
            System.out.println(b == compare);
            System.out.println(d == compare);
            System.out.println(e == compare);
        }
    
    

    输出:

    false
    true
    false
    

    编译器优化是有选择的,其实只要记住一句话就行了:只有编译阶段能确定的值,编译器才可以进行优化
    我们回过头来看上面的代码,a是一个局部变量,后期还可能会被赋值,编译器不确定它的值,所以不会对b的值进行优化,所以此时在进行+运算给b赋值的时候被编译为下面的语句:

    StringBuilder temp = new StringBuilder();
    temp.append(a).append("b");
    String b = temp.toString();
    

    第二个输出为true,是因为增加了一个final声明,从而强制约束c是不可以改变的,编译器知道c不可改变,所以自然将d的赋值过程优化,指向静态区ab的地址;

    第三个输出为false,同样的道理,getA()返回一个常量的引用,但是编译器并不能确切知道函数返回的值是什么,否则需要将函数执行一遍,所以这部分没有进行优化,结果应该为false

    intern

    String a = "a";
    String b = a + "b";
    String c  = "ab";
    String d = new String(b);
    
    System.out.println(b == c);
    System.out.println(c == d);
    System.out.println(c == d.intern());
    System.out.println(b.intern() == d.intern());
    
    false
    false
    true
    true
    

    看到上面的结果感到意外吗?其实熟悉了intern的用法就会明白。
    运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法.
    String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池。

    相关文章

      网友评论

          本文标题:java关于String的编译优化

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