<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />您能把這六個方面的改進概括一下嗎?
那好,我做一個簡述:
- 泛型Generic – 提供了collection操作的編譯期類型安全,並且避免了類型轉換的苦差事。
- For循環增強Enhanced for loop – 避免使用容易引起錯誤的迭代器.
- 自動置入/自動取出Autoboxing/unboxing – 避免了在基本類型(如int)和包裝類型(如Integer)之間人工轉換類型的苦差事。
- 類型安全的枚舉Typesafe enums – 提供了類型安全的枚舉模式((Effective Java, Item 21))的好處,卻沒有冗長和易錯的代碼。
- 靜態導入Static import – 讓你可以避免使用類的靜態變量而必須前綴類名;而且避免了常數接口的缺點(Effective Java, Item 17)。
- 元數據 – 讓你避免寫樣本代碼。你在程序中做標記然後工具自動幫你生成樣本代碼。這會導致一種聲明式的程序設計方格,你說應該做什麼,然後工具就會產生代碼完成這個任務。
如果遵循新規範並且開始使用泛型,那麼現在使用集合的方式和使用帶泛型的集合有什麼不同之處?
我們一般這樣使用集合:
/**
* 在由String構成的集合中刪除所有長度爲4的元素
* 傳入的集合必須由String構成
*/
static void expurgate(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
String s = (String) i.next();
if(s.length() == 4)
i.remove();
}
}
這個類型轉換並不完美,而且更重要的是程序可能會在運行時發生錯誤。假設用戶不小心傳入一個由StringBuffer構成的集合而不是註釋中說明的String,那麼就可能會有意外發生。註釋說客戶端必須傳入一個由String構成的集合,但是並不能要求編譯器編譯時一定滿足註釋。
下面是同樣的代碼使用泛型的例子 :
/**
*在由String構成的集合中刪除所有長度爲4的元素
*/
static void expurgate(Collection<String> c) {
for (Iterator<String> i = c.iterator(); i.hasNext(); )
if (i.next().length() == 4)
i.remove();
}
現在從代碼的簽名就可以看出,輸入參數必須是僅僅由String構成的集合。如果客戶試圖傳入一個由StringBuffer構成的集合,程序就不會通過編譯。而且請注意我們上面的代碼中並沒有類型轉換。它只有短短的一行,而且閱讀使用泛型集合的代碼也會非常清晰。
請您給我們介紹一下 "for增強"?
我們可以使用更優雅的方法遍歷一個集合。你一般遍歷集合的時候,都只是取元素,很少用到其他的方法。"for增強"可以讓編譯器代替你管理你的迭代器。例如,這是一個使用迭代器遍歷一個由TimeTask構成的集合:
void cancelAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
TimerTask tt = (TimerTask) i.next();
tt.cancel();
}
}
現在我們用"for增強"重寫一下這個方法:
void cancelAll(Collection c) {
for (Object o : c)
((TimerTask)o).close();
}
當你讀這個語句的時候,其中的分號讀作“在其中”。如果我們使用兩個新關鍵字foreach和in將會更加自然,不過引入新關鍵字會比較麻煩。比如如果我們現有的代碼中如果正好使用這兩個字作爲標誌符的話,那麼新的編譯系統就會破壞我們的原有代碼。我們的方法是在保留兼容性的基礎擴充語言。