久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Eclipse V3.1 中的 Java 泛型支持

 昵稱2807 2009-08-10

Eclipse V3.1 中的 Java 泛型支持

級別: 中級

Neal Ford ([email protected]), 應用程序架構(gòu)師, ThoughtWorks

2005 年 12 月 08 日

Java™ 5 提供泛型支持,泛型支持是開發(fā)人員多年以來所要求的特性,。它代表了 Java 編程語言一次具有重要意義的升級,。像泛型這么復雜的技術,不僅對工具供應商也對開發(fā)人員帶來了挑戰(zhàn),。本文著重介紹 Eclipse 如何應對泛型挑戰(zhàn)以及泛型給 Java 語言帶來的變化,,展示了如何在 Eclipse 中充分利用泛型,包括對于快速幫助,、快速修復,、重構(gòu)和項目參數(shù)選擇的支持。此外,,還展示了完全泛型化語言的一些微妙而重要的方面,。

Java 中的泛型

幾乎從第一個版本開始,Java 技術的創(chuàng)立者們就已經(jīng)開始討論對該語言添加泛型支持,。C++ 通過標準模板庫對泛型進行支持,,但是由于缺少所有其他類(嵌入在 Java 語言中的 Object 類中)的一個統(tǒng)一父類,泛型的實現(xiàn)也受到阻礙,。Java 編程語言的泛型支持是其歷史上最重大的語法變化,。由于某些顯而易見的原因,,工具支持比其他 SDK 升級的步法要慢得多。盡管如此,,現(xiàn)在 Eclipse V3.1 已經(jīng)對這些語言的新特性有了出色的支持,。本文重點介紹其中的一些新特性。


Java 5 項目

為了打開 Eclipse V3.1 中的 Java 泛型支持,,需要在機器上安裝 Java 5,,從一些平常的地方都可以下載到 Java 5。泛型支持連同項目屬性一起出現(xiàn)在編譯器設置頁面,。這意味著像以前一樣,,每個項目具有獨立的 SDK 設置。為了創(chuàng)建使用泛型的項目,,必須在創(chuàng)建項目時指定語言級別或者通過現(xiàn)有項目的項目屬性指定語言級別,。

Java 5 設置使用兩個特定的屬性頁。第一個屬性頁指定編譯器設置,。


圖 1. 針對 Java 5 支持的特定于編譯器的設置
針對 Java 5 支持的特定于編譯器的設置

除非您已經(jīng)在 Eclipse for Java 5 中設置了默認項目設置,,否則需要為該項目覆蓋那些設置。JDK compliance 區(qū)域允許您決定源文件和類文件的設置,。當您把源文件設置為 5.0 級別時,,就會獲得很多新的內(nèi)容幫助和重構(gòu)選項。

另一個相關屬性對話框是樹型視圖中的 Errors/Warnings 區(qū)域,。


圖 2. 項目屬性的 Errors/Warnings 區(qū)域
項目屬性的 Errors/Warnings 區(qū)域

大量 J2SE 5 選項能夠控制 Eclipse 為您的 Java 5 代碼產(chǎn)生什么類型的錯誤和警告(請參見表 1)

表 1. Eclipse 為 Java 5 代碼產(chǎn)生的錯誤和警告
J2SE 5 選項 警告類型
Unchecked generic type operation 編譯器每當遇到未經(jīng)檢查的泛型類型操作,,就將發(fā)出一個錯誤或者警告。這種操作包括諸如 ListArrayList 等類型上的操作,,但沒有指定類型,。每當您使用一個保存有對象的舊式 Collection 類時就會產(chǎn)生一個警告。
Generic type parameter declared with a final type bound 編譯器每當遇到一個涉及 final 類型的類型綁定時,,就會發(fā)出一個錯誤或者警告,。請看這個示例方法簽名:

public int doIt(List<? extends String> list)

因為 String 是 final 類型,參數(shù)不能擴展 String,,所以這樣寫比較有效:

public int doIt(List<String> list)
Inexact type match for vararg arguments 當編譯器不能從 varargs 參數(shù)確定開發(fā)人員的意圖時,,它將生成一個警告。有一些與數(shù)組相關的 varargs 是不明確的,。
Boxing and unboxing conversions 對自動裝箱操作發(fā)出警告(裝箱操作可能影響性能),,并且不再對類型包裝對象做對象身份的假設。這是一個默認狀態(tài)下被忽略的小警告,。
Missing @Override annotation 應該為任何重寫的方法包含 @Override 注釋,。缺少這個注釋可能表示開發(fā)人員沒有意識到該方法被重寫。
Missing @Deprecated annotation 由于缺少 @Deprecated 標志而產(chǎn)生的警告,。
Annotation is used as super interface 您不能把 Deprecated 類作為超級接口,。例如,不推薦這種寫法:

public interface BadForm extends Deprecated {

}

,。
Not all enum constants covered on switch switch 語句缺少枚舉項意味著您可能遺漏一些枚舉選項,。
Unhandled warning tokens in @SuppressWarnings Java 5 允許您添加注釋以抑制編譯器警告。如果您拼寫錯了一個警告或者使用了一個并不存在的警告,,這個標志將發(fā)出一個警告,。
Enable @SuppressWarnings annotations 打開程序地(用代碼)抑制您不關心的警告的能力。

一旦您根據(jù)喜好設定了所有的項目選項,,就可以開始在 Eclipse 中使用泛型了,。


從特定類型向泛型轉(zhuǎn)換

請考慮清單 1 中的簡單類,它創(chuàng)建了一個 EmployeeManager 對象的列表(Manager 擴展自 Employee),,將他們打印出來,,給他們漲工資后再打印出來。


清單 1. HR 類
package com.nealford.devworks.generics.generics;
                        import java.util.ArrayList;
                        import java.util.Collections;
                        import java.util.List;
                        public class HR {
                        public HR() {
                        List empList = new ArrayList(5);
                        empList.add(new Employee("Homer", 200.0, 1995));
                        empList.add(new Employee("Lenny", 300.0, 2000));
                        empList.add(new Employee("Waylon", 700.0, 1965));
                        empList.add(new Manager("Monty", 2000.0, 1933,
                        (Employee) empList.get(2)));
                        printEmployees(empList);
                        System.out.println("----- Give everyone a raise -----");
                        for (int i = 0; i < empList.size(); i++)
                        ((Employee) empList.get(i)).applyRaise(5);
                        printEmployees(empList);
                        System.out.println("The maximum salary for any employee is "+
                        Employee.MAX_SALARY);
                        System.out.println("Sort employees by salary");
                        Collections.sort(empList);
                        printEmployees(empList);
                        System.out.println("Sort employees by name");
                        Collections.sort(empList, new Employee.NameComparer());
                        printEmployees(empList);
                        System.out.println("Sort employees by hire year");
                        Collections.sort(empList, Employee.getHireYearComparator());
                        printEmployees(empList);
                        }
                        public void printEmployees(List emps) {
                        for (int i = 0; i < emps.size(); i++)
                        System.out.println(emps.get(i));
                        }
                        public static void main(String[] args) {
                        new HR();
                        }
                        }

如果您打開了 Java 5 支持,,編譯這段代碼會出現(xiàn)多種警告信息,。


快速修復特性

每當 Eclipse 要給您的代碼建議一種改進時,Eclipse 的快速修復特性就顯示為編輯器窗口左側(cè)邊欄上的一個燈泡,。在清單 1 中的代碼中,,您將會看到多個快速修復。


圖 3. 快速修復燈泡指示您的代碼待改進
快速修復

快速修復使用燈泡和黃色波浪線指示待改進處,。如果將鼠標移動至黃色波浪線上,,可以看到出現(xiàn)在圖 4 中的改進建議。


圖 4. 快速修復指示什么應該被通用化
快速修復指示什么應該被通用化

這里所列的快速修復建議只有一條建議,。邊上的燈泡提出建議,,添加一個本地變量保存 Listadd() 方法的返回值。然而,,在這里該方法返回一個布爾類型值,,并且被忽略了。

為了定位快速修復建議,,移至重構(gòu)菜單。Eclipse 中很多重構(gòu)與 Java 5 中的泛型直接相關,。“Infer Generic Type Arguments”重構(gòu)將給列表增加泛型支持,。 第一個對話框允許您選擇選項,。


圖 5. Infer Generic Type Arguments choices 對話框
Infer Generic Type Arguments choices 對話框

第一個選項與一個結(jié)論相關,,這個結(jié)論是 clone() 方法將返回接收者類型而不是另外一個類型(相關類),。大部分功能良好的類都遵守這個規(guī)則,如果您知道您的類不遵守這個規(guī)則,,則不要選中這個選項,。當?shù)诙€選項未選中時,,將保留“raw”(非泛型)參數(shù),,而不是推斷出正確的泛型參數(shù)類型。

Eclipse 中的大多數(shù)重構(gòu)中,,您都可以預覽您的類將發(fā)生什么變化,。點擊這個對話框上的 Preview 按鈕將出現(xiàn)圖 6 所示的對話框,。


圖 6. Preview the generic refactoring
Preview the generic refactoring

更新后的代碼如下:


清單 2. 更新后的代碼
List<Employee> empList = new ArrayList<Employee>(5);
                        empList.add(new Employee("Homer", 200.0, 1995));
                        empList.add(new Employee("Lenny", 300.0, 2000));
                        empList.add(new Employee("Waylon", 700.0, 1965));
                        empList.add(new Manager("Monty", 2000.0, 1933,
                        empList.get(2)));
                        

代碼發(fā)生了兩個有趣的變化。第一 —— 也是最明顯的 —— ListArrayList 聲明現(xiàn)在是 Employee 類型的泛型。第二 —— 不太明顯 —— 代碼最后一行發(fā)生的變化,。您觀察一下 Manager 類的原來的 empList 添加,它的最后一個參數(shù)需要針對 Assistant 域強制類型轉(zhuǎn)換為 Employee。而 Infer 重構(gòu)足夠聰明,它可以刪除現(xiàn)在不必要的類型強制轉(zhuǎn)換,。

在介紹完快速修復之前,,Eclipse 還在 Java 5 支持中增加了另外一個有趣的方面:您可以得到為方法添加注釋的建議,,比如 @Override,。您還具有針對注釋的內(nèi)容幫助,。


圖 7. 針對注釋的快速修復和內(nèi)容幫助擴展
針對注釋的快速修復和內(nèi)容幫助擴展

快速幫助特性

Eclipse V3.1 已經(jīng)添加了快速幫助以促進 Java 5 中的泛型支持。請考慮這個普通的 for() 循環(huán),,參見清單 3 中的 printEmployees() 方法。


清單 3. for() 循環(huán)
public void printEmployees(List<Employee> emps) {
                        for (int i = 0; i < emps.size(); i++)
                        System.out.println(emps.get(i));
                        }
                        

除了對泛型的支持外,,Java 5 現(xiàn)在也支持 for...each 循環(huán),。快速幫助建議將 for loop 變成 for...each,,變化后的代碼如清單 4 所示,。


清單 4. for...each 循環(huán)
public void printEmployees(List<Employee> emps) {
                        for (Employee emp : emps)
                        System.out.println(emp);
                        }
                        

這個版本由于完全刪除了 i 變量和 get() 方法調(diào)用而變得清潔多了。


泛型類型

Eclipse V3.1 為了擴展到泛型類型而擴大了對類型操作的支持,。這意味著:

  • 泛型類型能夠被安全地重命名,。
  • 類型變量能夠被安全地重命名。
  • 泛型方法能夠從泛型代碼中抽象出來或者嵌入泛型代碼,。
  • 代碼幫助可以自動將合適的類型參數(shù)插入?yún)?shù)化的類型中,。

Eclipse 中的搜索工具對于泛型類型已經(jīng)具有了更高的智能性,。請考慮如下代碼:


清單 5. 泛型類型
public void doEmployeeAnalysis() {
                        List<Employee> empList = new ArrayList<Employee>(5);
                        List<Date> hireDates = new ArrayList<Date>(5);
                        List<Integer> departments = new ArrayList<Integer>(10);
                        List<? extends Employee> allMgrs = new ArrayList<Manager>(5);
                        . . .
                        

如果您選中第一個 List<Employee> 聲明并且選擇 Search > References > Project,Eclipse 將顯示給您所有的 list 聲明,。


圖 8. Eclipse 在尋找泛型引用方面已經(jīng)變得聰明
Eclipse 在尋找泛型引用方面已經(jīng)變得聰明

您也可以通過 Search 窗口隱藏良好的特性來過濾這些結(jié)果。如果您訪問 Search 窗口菜單(在右上角,,最小化和最大化按鈕的旁邊),,您可以找到泛型感知的過濾選項,。


圖 9. 搜索窗口的過濾菜單允許您過濾泛型感知的結(jié)果
搜索窗口的過濾菜單允許您過濾泛型感知的結(jié)果

如果您使用 Filter Incompatible 過濾結(jié)果,,將刪除兩個不是基于 Employee 的條目,。結(jié)果如圖 10 所示,。


圖 10. Filter Incompatible 在搜索窗口過濾掉與非 Employee 相關的條目
 Filter Incompatible 在搜索窗口過濾掉與非 Employee 相關的條目

深入了解泛型

不幸的是,Eclipse 不能解決您所有的泛型問題。事實上,,有時重構(gòu)會為您要解決的問題產(chǎn)生語法正確但是語義不正確的代碼。具有諷刺意味的是,在泛型出現(xiàn)之前的那些日子更輕松,因為您必須將所有東西都作為對象的泛型集合傳遞。而現(xiàn)在您必須小心地傳遞正確類型的集合。

考慮這個例子,。在 HR 應用程序中,,您添加一個方法確定雇員的退休年齡,。然而,Employee 的年齡是來自于 Employee 的父類:Person,。寫一個方法只接受在這個實例中工作的雇員,,但是您不想將您的應用程序只用于雇員。如果將來您需要查詢以前的雇員(作為 Persons),,該怎么辦呢,?

這個問題的解決方案在于靈活的泛型參數(shù)。請考慮清單 6 中的代碼,,它接受任何擴展自 Person 的類,。


清單 6. 示例 SELECT 語句
public List<Person> empsOverRetirementAge(
                        List<? extends Person> people) {
                        List<Person> retirees = new ArrayList<Person>(1);
                        for (Person e : people)
                        if (e.getAge() > 65)
                        retirees.add(e);
                        return retirees;
                        }
                        

該方法接受 Person 的任何子類,所以更靈活,。使用泛型的時候,,您應該牢記這一點。在本例中,,泛型實際上比較特定(至少,,他們應該稱這種語言特性為“特定性”)。仔細識別參數(shù)類型能夠使您的代碼獲得同樣的靈活性,,因此性能比泛型更好,,但是具有泛型提供的附加的類型安全性。

泛型支持大大增強了 Java 編程語言,,工具供應商必然需要很長時間才能趕上?,F(xiàn)在有了好的工具支持,您應該開始利用這種高級語言特性,。它使代碼更加可讀 —— 因為刪除了類型強制轉(zhuǎn)換 —— 并且允許編譯器為您做更多的工作,。任何時候您都可以讓編譯器和其他的工具(如 IDE)做更多的工作,,這意味著您要做的工作更少。


參考資料

學習

獲得產(chǎn)品和技術
  • 使用 IBM 測試軟件 改進您的下一個開放源碼開發(fā)項目,可以通過下載或從 DVD 中獲得這些軟件,。


討論


關于作者

Neal Ford 是 ThoughtWorks 的應用程序架構(gòu)師,ThoughtWorks 是一個 IT 專業(yè)服務公司,。他還是應用程序、教學材料,、雜志文章,、課件、視頻/DVD 演示文稿的設計者和開發(fā)者,,還是 Developing with Delphi: Object-Oriented Techniques,、JBuilder 3 Unleashed 和 Art of Java Web Development 等書籍的作者。他主要是構(gòu)建大型企業(yè)應用程序方面的顧問,。他還在許多開發(fā)人員研討會上做過演講,。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多