天天看點

JAVA FINAL修飾幾種變量的差別

1:final變量和普通變量

public class Test {

    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。

當final變量是基本資料類型以及String類型時,如果在編譯期間能知道它的确切值,則編譯器會把它當做編譯期常量使用。也就是說在用到該final變量的地方,相當于直接通路的這個常量,不需要在運作時确定。由于變量b被final修飾,是以會被當做編譯器常量,是以在使用到b的地方會直接将變量b 替換為它的值。而對于變量d的通路卻需要在運作時通過他的位址确定。

(a,b的值在運作是可以确定就是hello和hello2,運作時a編譯後放在常量池,運作時編譯b,也放在常量池,然後編譯c,b的值可以确定,拼接後放在常量池内,已經存在一個一樣的值,a == c.但是 d在運作時需要通過位址确定值,兩者指向不是同一個地方。)

---------編譯期間的可确定的常量全部存放在常量池(棧),運作期間新産生的對象不管值是否相同,都在堆中,即使内容相同,也指向不同的記憶體位址。

public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = getHello();
        String c = b + 2; 
        System.out.println((a == c));
    }

    public static String getHello() {
        return "hello";
    } 
}
           

輸出結果分别為FALSE。

編譯期間不能确定 b 的值,隻有在運作時才可以。

注:使用equals()和==,差別在于equals比較的是内容是否相等、==比較的是引用的變量位址是否相等。String 是不可變對象。

2:final修飾的引用變量

引用變量被final修飾之後,雖然不能再指向其他對象,但是它指向的對象的内容是可變的。