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 ?
廢話不多說,直接看程式碼!(程式碼看多了,反而覺得中文字比較難理解)
上面是一個簡單的範例,用final修飾一個名為mArray的整數陣列,第二行則是印出此陣列的第0個元素,輸出毫無意外的是1。接著看下一個範例。
大家都知道這一定會出錯,因為mArray是final的狀態,不能被修改,編譯系統也會告訴你「error: cannot assign a value to final variable mArray」。再來看下一個範例。
我一開始以為會編譯失敗,就如同一開始的解釋,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),但這個參考裡面所表示的內容,是可以修改的。
參考資料:
[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]);
}
}
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};
}
}
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]);
}
}
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),但這個參考裡面所表示的內容,是可以修改的。
分享一下~
回覆刪除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)來看,雖然不是真的記憶體位置,但性質是一樣的~
長知識了,感謝你的分享!
刪除