注意:List.of() 出現在JDK9.0以後,JDK8.0的廣大用戶是用不到的。
不知道看過這兩個方法的人,會不會也覺得它們是同一種效果呢?
在這兩個方法中我們可以放入不定長度的引數,來快速建立出一個List,而且是沒辦法對它操作add(), remove()的List。
List.of(1, 2, 3);
Arrays.asList(1, 2, 3);
那它們到底有沒有差別?答案是有的。
Arrays.asList()方法所傳回的List表面上感覺會是不可變的(immutable),但若我們傳進的是一個陣列,而在其他地方對這個陣列引數做操作,那Arrays.asList()傳回的List也會跟著被改變了:
int[] intArray = {1, 2, 3};
List<Integer> intList = Arrays.asList(intArray);
intList.add(4); // this will throw UnsupportedOperationException
intArray[2] = 4
System.out.println(intList); // [1, 2, 4]
這可以說是假的immutable,因為所傳回的List還是改變了狀態~仍然有副作用產生(Side Effect);這種在第一手操作上看似immutable的狀態,稱之為unmodifiable,而不會是真正的immutable。
那我們來看看List.of():
int[] intArray = {1, 2, 3};
List<Integer> intList = List.of(intArray);
intList.add(4); // this will throw UnsupportedOperationException
intArray[2] = 4
System.out.println(intList); // [1, 2, 3]
哦哦~可以看到,就算我們之後改變了引數陣列的狀態,但List.of()所回傳的List狀態還是維持在當初回傳的狀態,貌似達到了真正的immutable呢!
但為什麼我們要說"貌似"呢?
很遺憾的,如果我們的陣列放的不是基本型態,而是我們自己定義的類別物件時,那當各個元素的物件狀態發生改變,元素內的狀態還是跟著改變;List.of()不會這麼勤勞的幫我們把各個元素都做深拷貝。
所以若要確保List.of()回傳的List完完整整的是immutable,那必須也要在放入的元素類別中確保每個屬性(field)也是immutable才行。