Project Coin 裡的最後一個新功能叫 簡化變動參數方法的呼叫 (Simplified varargs method invocation),從名稱上看不出個所以然,它又跟昨天提到的 Heap Pollution 有什麼關係呢?
變動參數也是在 Java 1.5 中新增的功能,而它特殊的 … 語法,實際上就是轉換成陣列使用,再配合泛型的不特定型別的宣告,在某些情況下,也是會造成 Heap Pollution。請看下面這個例子:
package idv.jacky.ironman4.day26;
public class Day26Example1 {
public static void main(String[] args) {
System.out.printf("Sum = %d%n", Util2.sum(args));
}
}
package idv.jacky.ironman4.day26;
public class Util2 {
public static <T> int sum(T...numbers) {
int sum = 0;
for(T i : numbers)
sum += ((Number)i).intValue();
return sum;
}
}
我們把 sum 方法的參數,改成使用 varargs 的語法,我們大譫地假設呼叫 sum 方法的人,所傳進來的物件,都是 Number 類別的物件,或其子類別物件,例如 Integer, Double等…然後呼叫 Number 的 intValue 方法,再把它們通通加起來。
問題就出在我們的「大膽假設」上,T 指的是不定型別,也就是說我們不把 sum 方法的參數型別給寫死,完全在執行時期時,才去動態的傳入。問題就在於如果傳入的不是 Number 或其子類別物件的話,那就會遇到 Heap Pollution 的問題。
上面的範例,在編譯時加上 XIint:unchecked 的參數的話,就會看到 Java 所丟出來的警告訊息:
**/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/bin/javac -Xlint:unchecked Util2.java
Util2.java:6: warning: [unchecked] Possible heap pollution from parameterized vararg type T
public static <T> int sum(T...numbers) {
^ where T is a type-variable:
T extends Object declared in method <T>sum(T...)
1 warning
[b]
這次 Java 就很明確的告訴你,Util2.sum 方法可能會有 Heap Pollution 的問題!
如果我們真的非常肯定,Util2.sum 方法只有我們自己會用,且一定會傳入正確型別的變數進去,例如:
package idv.jacky.ironman4.day26;
import java.util.ArrayList;
import java.util.List;
public class Day26Example2 {
public static void main(String[] args) {
List<Double> numbers = new ArrayList<>();
for(String str : args)
numbers.add(Double.parseDouble(str));
System.out.printf("Sum = %d%n", Util2.sum(numbers));
}
}
我們不想在編譯時看到剛剛的警告訊息的話,在 Java SE 7 之前,我們可以用一個 Annotation - [b]@SuppressWarings("unchecked")** 來壓制這個警告。在 Java SE 7 裡則多了一個新的 Annotation 特別設計給 varrags 用的,就是 @SafeVarargs。效果跟 @SuppressWarings("unchecked") 一樣,我們在 sum 方法宣告的的上一行加上 @SafeVarargs,
@SafeVarargs
//@SuppressWarnings("unchecked")
public static <T> int sum(T...numbers) {
這樣編譯器就會認為你已經知道 Heap Pollution 的風險,而略過對這個方法提出警告。
不過,這只是把警告給壓制下來,實際上 Heap Pollution 的問題並沒有消失,所以在呼叫這類的方法時,還是得特別地注意。