iT邦幫忙

DAY 26
2

實戰 Java SE 7 系列 第 26

Project Coin - Simplified varargs method invocation

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 的問題並沒有消失,所以在呼叫這類的方法時,還是得特別地注意。


上一篇
複習 - Heap Pollution
下一篇
Unicode 6.0 簡介
系列文
實戰 Java SE 7 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言