1. 程式人生 > >final修飾的變量引用不能變還是對象不可變

final修飾的變量引用不能變還是對象不可變

報錯 -- class new http 基本 賦值 技術 ati

兩種情況:如果是基本數據類型,被final修飾的變量一旦初始化就不能改變;如果是引用數據類型的變量,初始化之後不能只想另外一個對象。

基本數據類型:

package cn.yqg.day2;

public class StringTest {
     public static void main(String[] args) {
        final int a;
        int b=234;
        a=b;
        System.out.println(a);
    }
}

我們看到上面的代碼a是final類型的,但是沒有被初始化,所以可以給a賦值。如果a被初始化,a存儲的值就不能改變了,示例如下。

package cn.yqg.day2;

public class StringTest {
     public static void main(String[] args) {
        final int a=123;
        int b=234;
        a=b;//編譯通不過,會報錯建議去掉fianl
        
        System.out.println(a);
    }
}

如果是引用數據類型

-----------------------------------------------------------------------------------------------------------------------------------------------------------------

package cn.yqg.day2;

public class StringTest {
     public static void main(String[] args) {
        final StringBuffer a=new StringBuffer("ppp");
        System.out.println(a);
        System.out.println(a.hashCode());
        a.append("kkk");
        System.out.println(a);
        System.out.println(a.hashCode());
        
    }
}

運行結果:

ppp
2018699554
pppkkk
2018699554

我們發現變量內容變了,引用沒變。

我們把String定義為final類型,那麽String類不能被繼承,引用不能被改變,但是引用地址指向的內存的地址存儲的對象是可以改變的

String a="ppp";
 a=a+"kkk";

我們看到a的對象內容改變了

不允許String類的引用被改變是為了安全性著想,我們看這個例子。

package cn.yqg.day3;

public class Test2 {
    public static void main(String[] args) {
        String a=new String("fds");
        String b=new String("ddd");
        String c=b;
        c=c+"ds";
        System.out.println(b);
        System.out.println(c);
    }
}

運行內存圖:

技術分享圖片
運行結果:

ddd
dddds

我們從此可以知道,上面的String c=b;並不是將b的地址復制給c,而是c新開辟一個地址並進行存貯,這就保證了String類的安全性,相反StringBuilder就存在安全隱患

package cn.yqg.day3;

public class Test2 {
    public static void main(String[] args) {
        StringBuilder s=new StringBuilder("ppp");
        StringBuilder r=s;
        r.append("kkk");
        System.out.println(r);
        System.out.println(s);
    }
}

運行結果:

pppkkk
pppkkk

r改變會導致s也改變,因為他們指向得內存地址一樣。

------------------------------------------------------------------------------------------------------------------------------------------------------

final修飾的變量引用不能變還是對象不可變