zoukankan      html  css  js  c++  java
  • JavaSe: String的编译期优化

    Java的编译期优化

    因为工作的原因,经常会在没有源码的情况下,对一些产品的代码进行阅读。有时在解决Bug时,在运行环境下会直接去看class文件的字节码,来确定运行中版本是否正确的。

    在看字节码时,发现了一个有意思的现象:即便你在代码中使用了定义的常量,反编译后的代码仍会是字符串的字面量。

    这个其实就是Java编译器在编译时做了优化,下面就用一个例子来说明一下:

    public class StringTest {
        public static final String a1="a";
        public static String a2="a";
        public static void main(String[] args) {
            String a = "a";
            final String b = "b";
            final String c = a + b;
            String d = a + b;
            String e = a + "b";
            String f = "a" + b;
            String g = "a" + "b";
            String h = "ab";
            String i = new String(h);
            String j = a1+b;
            String k = a2+b;
    
            System.out.println(c == h); // false
            System.out.println(d == h); // false
            System.out.println(e == h); // false
            System.out.println(f == h); // true
            System.out.println(g == h); // true
            System.out.println(i == h); // false
            System.out.println(j == h); // true
            System.out.println(k == h); // false
            
            // 字面量,final 都会在编译期被优化,并且会被直接运算好
            // 所以 f,g,j 在编译期就直接变为"ab"
            // 因为a,a2是变量, 所以使用到a,a2的表达式,都是在运行时才去计算的
        }
    }

     使用 javap命令查看字节码如下:

    结合localvariabletable,分析main执行的过程如下:

     

    从这里面,可以很明显的看到 运行时加载到f,g,h,j 时,直接就是字面量“ab”。

    java中的==的作用是值的比较:

    1)对于boolean,int,char,short,double,float,byte,long 这8种基本类型的比较,是比较值是否相等。

    2)对于对象的比较,是比较地址的。

     字符串字面量,和用final 修饰的 boolean,int,char,short,double,float,byte,long的变量一样,被统称为常量,它们是存在于常量池中的。

    常量池中的内容只保留一份。上面例子中的f,g,j,h都是常量,它们的地址是同一个。所以比较的结果就是true。

    而其它的,都是在运行时计算出来的,他们是在heap内存区域的(与常量池不在同一区域),所以他们的地址也就不一样了。所以比较的结果就是false了。

    同理,对于其它的 boolean,int,char,short,double,float,byte,long常量 ,也会在编译期进行优化的。

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 快速幂
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    Java实现 蓝桥杯VIP 算法提高 最长字符序列
    linux下配置QT(很全的步骤,从下载开始,配置QMAKESPEC)
    QT 读取文件夹下所有文件(超级简单的方法,不需要QDirIterator)
    Windows平台下的图形化的Ping工具
    Qt中的键盘事件,以及焦点的设置(比较详细)
  • 原文地址:https://www.cnblogs.com/f1194361820/p/8012393.html
Copyright © 2011-2022 走看看