java之常量摺疊

qq_42606051發表於2018-09-21

為什麼會寫著篇部落格,因為昨天看了關於final關鍵字的解析。但是有個問題始終沒有得到解決,於是請教了我qq上之前新增的知乎大神。他給我回復的第一條訊息:常量摺疊。身為渣渣猿的我立馬查詢了這個概念。這是第一次知道這個概念。知乎大神還給我講了好多。讓我終於明白了這個常量摺疊的概念

例項解析

昨天,讓我迷惑的程式碼是下面這段程式碼

    public static void main(String[] args) {

        String a = "hello2";
        final String b = "hello";
        String d = "hello";
        String c = b + 2;
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));

    }

這段的執行結果是

true
false

我就是不明白為什麼第一個返回true呢?

留著這個疑問,我們先了解下常量摺疊的概念。來更好的理解上面的程式碼

常量摺疊

常量摺疊的概念

  • 常量摺疊是一種編譯器優化技術。
  • 常量摺疊主要指的是編譯期常量加減乘除的運算過程會被摺疊

對於 String s1 = "1" + "2";
編譯器會給你優化成 String s1 = "12";
在生成的位元組碼中,根本看不到 "1" "2" 這兩個東西。

我們通過idea進行驗證下

1、原始碼檔案

    public static void main(String[] args) {
        String s1 = "1"+"2";
    }

2、執行後,idea有個out資料夾,找到上面檔案的class檔案

    public static void main(String[] args) {
        String s1 = "12";
    }

確實如上面所說,編譯器會給你進行優化

常量摺疊發生的條件

  • 必須是編譯期常量之間進行運算才會進行常量摺疊。
  • 編譯期常量就是“編譯的時候就可以確定其值的常量”
    • 首先:字面量是編譯期常量。(數字字面量,字串字面量等)
    • 其次:編譯期常量進行簡單運算的結果也是編譯期常量,如1+2,"a"+"b"。
    • 最後:被編譯器常量賦值的 final 的基本型別和字串變數也是編譯期常量。

舉個例子

1.第一個栗子

    public static void main(String[] args) {
        String s1="a"+"bc";
        String s2="ab"+"c";
        System.out.println(s1 == s2);
    }

相信大家都知道了,輸出為true
並且只建立了一個 "abc" 字串物件,且位於字串常量池中。

2、第二個栗子

    public static void main(String[] args) {
        String a = "a";
        String bc = "bc";
        String s1 = "a" + "bc";
        String s2 = a + bc;
        System.out.println(s1 == s2);
    }

這個結果呢?false

s1 是字串字面量相加,但是 s2 卻是兩個非 final 的變數相加,所以不會進行常量摺疊。

而是根據 String 類特有的 + 運算子過載,變成類似這樣的程式碼

String s2 = new StringBuffer(a).append(b).toString(); 

這裡toString()會生成新的String變數,顯然用 == 運算子比較是會返回 false。

3、第三個栗子

    public static void main(String[] args) {
        final String a = "a";
        final String bc = "bc";
        String s1 = "a" + "bc";
        String s2 = a + bc;
        System.out.println(s1 == s2);
    }

這裡的結果就是true

因為 被編譯器常量賦值的 final 的基本型別和字串變數也是編譯期常量

4、第四個栗子

    public static void main(String[] args) {
        String x ="a";
        final String a = x;
        final String bc = "bc";
        String s1 = "a" + "bc";
        String s2 = a + bc;
        System.out.println(s1 == s2);
    }

這裡的結果是false

這裡需要注意的是:final的變數,不是被編譯期常量初始化的也不是編譯器常量

這裡的a 就不是編譯器常量

總結

現在看完,是不是對上面列印的結果為什麼是true 知道了呢?
所以。只要牢記常量摺疊主要指的是編譯期常量加減乘除的運算過程會被摺疊

作者:養碼青年

出處:https://www.cnblogs.com/zhenghengbin/p/9683990.html

鄭州婦科醫院

鄭州治療婦科哪家醫院好

鄭州治療婦科哪家醫院好

鄭州專業婦科醫院

相關文章