2014-09-26 15 views
4

當泛型在Java 6中沒有定義兩次時會發生什麼「壞事(tm)」?Java 6:爲什麼要定義泛型兩次?

List<String> foo = new ArrayList();

代替

List<String> foo = new ArrayList<String>();

因爲這兩種編譯罰款,以我的經驗,並且運行良好,以及。

在Java 7中,可以使用鑽石算子完全避免這種情況。

List<String> foo = new ArrayList<>();

這更加緊密地遵循DRY原則。

回答

8

當通用性在 Java 6中沒有定義兩次時會發生什麼「壞事(tm)」?

在缺省無參數構造函數的情況下可能沒有什麼不好,就像ArrayList的情況那樣,但如果有一個列表構造函數需要一個泛型參數,例如

class MyList<T> implements List<T> 
{ 
    T firstValue; 

    public MyList(T value) 
    { 
    firstValue = value; 
    } 
} 

Apple apple = new Apple(); 

// This compiles fine, and now we have a problem 
// Hence the warning 
MyList<Orange> foo = new MyList(apple); 

// This does not compile 
MyList<Orange> foo = new MyList<Apple>(apple); 

// Nor this in Java 7 
MyList<Orange> foo = new MyList<>(apple); 
0

這只是一個語法,當你運行你的程序時,java不知道你的集合的泛型類型。

關於泛型的所有提示/檢查都在編譯時發生。如果您首先要聲明的變量一樣

List<String> foo; 

然後初始化它像

foo = new ArrayList(); 

你會得到一個警告,原因編譯器有一個懷疑,你忘了聲明泛型類型的foo的。使用顯式泛型類型進行初始化可確保編譯器記住一切正常。

是的,它太羅嗦了,這就是爲什麼它在Java 7中被替換爲鑽石運算符<>沒有什麼特別的。

6

DRY原則很重要,但也有一個原則:「不要在代碼中留下代碼以生成警告」。即使你完全理解了原因,並且知道它完全無害,消除警告也是一種好習慣。

List<String> foo = new ArrayList(); 

編譯但生成編譯器警告,除非你用@SuppressWarnings註釋它。通常將其寫成

List<String> foo = new ArrayList<String>(); 

並與重複同時存在。或者更好的是,升級到JDK7或更高版本。

我如何衡量這兩個原則的相對重要性取決於具體情況。 DRY違規行爲延伸到代碼的不同部分或不同文件中會很快變得無法忍受,但這裏DRY違規行爲僅限於一行。打字時有一些滋擾的價值,但有警告似乎是一個更大的滋擾,並且是一個不好的先例。