Java Final Array

Final是一個修飾詞(Non Access Modifier),可用於修飾類別(Class)、方法(Method)和變數(Variable)。修飾類別時,代表其類別不能被繼承;修飾方法時,代表其方法不能被覆寫(Override);修飾變數時,代表其變數是一個常數(Constant),無法被修改。但是,泰勞偶然地發現,這麼解釋並「不夠精確」,為甚麼呢?讓我們繼續看下去。

參考資料:
[Ken Yang 筆記]Java final 基本概念
[StackOverflow]final array in Java
[SoloLearn]Why can I modify the value of final array ? 

廢話不多說,直接看程式碼!(程式碼看多了,反而覺得中文字比較難理解)
public class MyArray{
    public static void main(String[] args){
        final int[] mArray = new int[]{1,2,3,4,5};
        System.out.println(mArray[0]);

    }
}

上面是一個簡單的範例,用final修飾一個名為mArray的整數陣列,第二行則是印出此陣列的第0個元素,輸出毫無意外的是1。接著看下一個範例。
public class MyArray{
    public static void main(String[] args){
        final int[] mArray = new int[]{1,2,3,4,5};
        System.out.println(mArray[0]);
        mArray = new int[]{6,7,8,9,0};
    }
}

大家都知道這一定會出錯,因為mArray是final的狀態,不能被修改,編譯系統也會告訴你「error: cannot assign a value to final variable mArray」。再來看下一個範例。
public class MyArray{
    public static void main(String[] args){
        final int[] mArray = new int[]{1,2,3,4,5};
        System.out.println(mArray[0]);
        //Cannot assign a value to final variable
        //mArray = new int[]{6,7,8,9,0};

        mArray[0] = 6;
        System.out.println(mArray[0]);
    }

我一開始以為會編譯失敗,就如同一開始的解釋,final變數不能被修改,而實驗結果證明這樣解釋並「不夠精確」。上面的程式碼不但可以成功編譯,還會輸出修改後的結果,如下圖所示。

 很神奇吧!我們來看看 Shehzad 對於此現象的解釋: 
final applies to the array object reference, which means once it is initiated, the reference can never change but the array its self can be populated.」

另一位SoloLearn上的網友 Rahul 的解釋如下: 
final keyword means that you can't change the reference of the constant Array, it doesn't mean that the array is immutable !

我的理解就是被final修飾的陣列,不能更動的是它的參考(Reference),但這個參考裡面所表示的內容,是可以修改的。

留言

  1. 分享一下~
    https://www.tutorialspoint.com/java/java_arrays.htm

    array的物件會記起始的記憶體位置(就是Reference,其他的物件也是,會依照資料型態再去決定要往後抓幾格的資料,不過也有其他更複雜的結構XD),所以改內容是ok的。
    但如果今天要在指定另一個array物件給mArray就會報錯嘍~

    ex:
    final int[] mArray1 = new int[]{1,2,3,4,5}; //Reference: 1639705020
    final int[] mArray2 = new int[]{1,2,3,4,5}; //Reference: 1639705018
    mArray1 = mArray2; //會報錯
    //只要用到new,就算內容一樣,也會產生新的物件

    這種情況下就會掉了,因為兩個物件的Reference不一定,又因等號('=')是將右邊的值assign給左邊,所以就出錯啦~

    java的Reference可以調用System.identityHashCode(object)來看,雖然不是真的記憶體位置,但性質是一樣的~

    回覆刪除

張貼留言

這個網誌中的熱門文章

程式語言常用之符號與詞彙 - 中英文對照

Repo 實用指令

什麼是 Bootloader?