iT邦幫忙

DAY 25
3

實戰 Java SE 7 系列 第 25

複習 - Heap Pollution

  • 分享至 

  • xImage
  •  

Java 從1.5 版加入泛型的功能後,一直有個潛在的使用問題,那就是 Heap Pollution
我們先來看看下面這個範例:

package idv.jacky.ironman4.day25;

import java.util.Arrays;
import java.util.List;

public class Day25Example1 {

	public static void main(String[] args) {		
		List numbers = Arrays.asList(args);
		System.out.printf("Sum = %d%n", Util.sum(numbers));
	}
}





package idv.jacky.ironman4.day25;

import java.util.List;

public class Util {
	public static int sum(List<Integer> ls) {
		int sum = 0;
		for(Integer i : ls)
			sum += i;
		
		return sum;
	}
}

你應該一眼就能看出來上面這個範例程式哪兒出了問題,問題就在於 Util.sum 方法只能接受 List<Integer> 的參數,但我們卻在第10行把一個 List 物件傳進去,而 List 物件則是透過 Arrays.asList 的方法,把 main 方法 的參數 args 字串陣列,轉成 List 物件。

程式在編譯時,Java 編譯器會丟出一個警告訊息:

javac Day25Example1.java
Note: Day25Example1.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

意思是說程式裡有個未受檢查或不安全的程式碼,建議你在編譯時加上 -Xlint:unchecked 來看詳細的資料。

javac -Xlint:unchecked Day25Example1.java
Day25Example1.java:10: warning: [unchecked] unchecked conversion
found : java.util.List
required: java.util.List<java.lang.Integer>
System.out.printf("Sum = %d%n", sum(numbers));
^
1 warning

Java 編譯器有檢查到,sum 方法的參數型別應該是 List<Integer>,但你給的是 List。

程式依然可以編譯成功,但執行時就會有例外出現:

所以 Heap Pollution 指的就是將一個未定參數型別的 Collection 物件,指定給一個有指定參數型別的 Collection 物件後,所隱藏的潛在問題。

既然知道這樣會有潛在的危險,因為我們不能確定所有呼叫 sum 方法的人,傳進來的都是 List<Integer> 物件,那為什麼不能在編譯時就給個錯誤,不讓程式編譯成功呢?主要的原因是,Java 無法知道誰會呼叫 sum 方法。我們的範例很簡單,你一下就看出來哪邊有問題,但今天如果 Util 類別是要給別人使用的,你並沒有辦法知道別人會不會正確的使用它。而 Java 程式裡變數的型別檢查,都是在編譯時其做的,在執行時期,是完全沒有型別資料的。一直要到發生例外時,我們才知道問題出在哪。

所以當你在編譯 Java 程式碼時,如果要你使用 -Xlint:unchecked 來察看詳細的警告資料時,請花點時間看一下,修正可能會發生錯的程式碼,這樣能確保你的程式能更安全、穩固地執行。


上一篇
Project Coin - try-with-resource 語法 完
下一篇
Project Coin - Simplified varargs method invocation
系列文
實戰 Java SE 7 31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言