HOWTO · Java
在 Java 的建構函式中初始化陣列
這篇文章是關於在 Java 的建構函式中初始化一個陣列。
本頁內容
建立 Java 物件時,如果陣列欄位的初始內容取決於建構子引數或其他設定,就在建構子中初始化該欄位。若 Java 的預設值符合需求,只要配置欄位即可。在建構子內宣告的區域變數只在建構子執行期間可用,不會成為物件狀態。
在 Java 建構子中初始化陣列欄位
先將陣列宣告為實例欄位,再於建構子中指派陣列參照。每建立一個新物件,建構子就會執行一次,因此可以根據該物件的輸入值設定欄位,或預先準備為該物件計算出的值。
陣列欄位與它所參照的陣列是兩個不同的東西:欄位存放參照,陣列則存放元素。使用 new int[size] 建立陣列時會配置元素,並為每個元素設定預設值。將區域陣列指派給欄位,例如 this.values = values,會儲存該參照;如果物件需要擁有獨立的內容,請使用複製後的陣列。
使用 Java 的陣列預設值
在建構子本體執行之前,Java 就會為實例欄位設定預設值。建構子建立陣列時,Java 也會初始化陣列元素:數值基本型別元素預設為零(整數型別為 0,float 和 double 為 0.0);char 元素為 \u0000,boolean 元素為 false,而 String 等參照型別元素則為 null。
例如,private int[] values = new int[3]; 會建立含有三個零值元素的實例欄位。你也可以先宣告 private int[] values;,再於建構子中指派 values = new int[3];;元素仍會以零作為初始值。如果指派這些值沒有表達其他需求,就不必再用迴圈寫入相同的值。
在建構子中指派特定值
若內容固定,可使用陣列初始設定式;若每個物件的初始內容應由呼叫端提供,則可將值設為建構子參數。例如,this.values = new int[] {1, 2, 3}; 會將這三個值設給欄位。使用參數的建構子可以直接指派輸入陣列,也可以先複製再指派,取決於呼叫端之後修改陣列時,是否也應影響物件。
下方範例在同一個類別中展示幾種作法:建立元素為預設值的欄位、複製提供的值、以單一值填滿另一個欄位、根據索引計算元素值,以及在建構期間使用區域陣列。程式會顯示每個陣列,方便你依照類別的需求採用合適的部分。
import java.util.Arrays;
public class ArraySetup {
private final int[] defaults = new int[3];
private final int[] supplied;
private final int[] repeated = new int[3];
private final int[] calculated = new int[3];
public ArraySetup(int[] source) {
supplied = Arrays.copyOf(source, source.length);
Arrays.fill(repeated, 7);
Arrays.setAll(calculated, index -> (index + 1) * 2);
int[] local = {4, 5};
System.out.println("Local: " + Arrays.toString(local));
}
public static void main(String[] args) {
int[] input = {3, 6, 9};
ArraySetup item = new ArraySetup(input);
System.out.println("Defaults: " + Arrays.toString(item.defaults));
System.out.println("Supplied: " + Arrays.toString(item.supplied));
System.out.println("Repeated: " + Arrays.toString(item.repeated));
System.out.println("Calculated: " + Arrays.toString(item.calculated));
}
}
在建構子中建立區域陣列
在建構子內使用 int[] local = {4, 5}; 這類宣告,會建立區域變數。建構子中的程式碼可以使用這個變數,但建構子返回後,其他方法就無法存取它。如果陣列應成為所建立物件的一部分,請改將它指派給實例欄位,例如 this.values = new int[] {4, 5};。
區域陣列仍可作為建立欄位時的暫存輸入,或用於只在設定期間需要的計算。請留意兩者的差異:如果欄位或其他物件儲存了陣列參照,陣列物件仍可能持續存在;但只有建構子區域變數本身,並不能讓陣列成為物件狀態的一部分。
使用 Arrays.copyOf()、Arrays.fill() 或 Arrays.setAll()
請依照陣列內容的決定方式選擇輔助方法。Arrays.copyOf(source, source.length) 會建立一個獨立陣列,其中包含來源陣列的元素。若指定的長度較短或較長,方法會複製可容納的元素;較長的複本中新增的元素則會取得其型別的預設值。對物件陣列而言,這是淺層複製:複製的是參照,不會複製參照所指向的物件。
如果每個元素都應設為相同值,請使用 Arrays.fill(array, value)。若要依索引計算每個值,請使用 Arrays.setAll(array, index -> expression)。在範例中,填入操作會將陣列元素全部設為 7,索引函式則會依序設定偶數。這些方法會更新傳入的陣列,不會建立替代陣列。
選擇合適的初始化方式
如果預設值就是預期的初始狀態,請建立指定大小的陣列並直接使用預設值。少量且固定的值可用陣列初始設定式;若由呼叫端選擇內容,則可使用建構子參數。當物件需要自己的陣列結構時,請複製輸入陣列;要重複填入單一值時使用 Arrays.fill(),要依索引設定值時使用 Arrays.setAll()。只要陣列在建構完成後仍須作為物件狀態使用,就應將它宣告為實例欄位。