構造器引用同方法引用類似,不同的是在構造器引用中方法名是new。例如,Button::new表示Button類的構造器引用。對於擁有多個構造器的類,選擇使用哪個構造器取決於上下文。假設你有一個字符串列表,並且希望調用Button類的構造器使用列表中的字符串來構造一個按鈕列表,可以使用如下表達式:
List<String> labels = ....;
Stream<Button> stream = labels.stream().map(Button::new);
List<Button> buttons = stream.collect(Collectors.toList());
後面我們會詳細討論stream,map和collect方法。但是現在,重要的是對於每個列表元素,map方法會調用Button(String)構造器。雖然Button類有多個構造器,但是編譯器會從上下文中推斷並挑選只帶一個String參數的構造器。
你可以使用數組類型來編寫構造器引用。例如,int[]::new是一個含有一個參數的構造器引用,這個參數就是數組的長度。它等同於lambda表達式 x -> new int[x]。數組構造器引用可以用來繞過java中的一個限制。在Java中,無法構造一個泛型類型T的數組。表達式 new T[n]是錯誤的,因為它會被擦除為new Object[n]。
對於編寫API的開發人員來說是一個問題。例如,假設我們希望構造一組按鈕,Stream接口中有一個返回Object數組的toArray()方法:
Object[] buttons = stream.toArray();
但這並不能讓我們滿意。用戶希望一組按鈕對象,而不是一組Object對象。Stream API通過構造器引用解決了這個問題。它允許將Button[]::new傳遞給toArray方法:
Button[] buttons = stream.toArray(Button[]::new);
toArray方法會調用該構造器來獲得一個正確類型的數組。然後它會填充並返回該數組。