小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Java語言基礎(chǔ)特性—第一部分(下)

 yxhuang 2014-05-16

你可以通過指定extends后接類型名稱來提供通配符的上界。同樣的,你可以通過指定super后接類型名稱來提供通配符的下界。這些限定限制了可以作為實(shí)際類型參數(shù)傳入的類型。

在例子中,你可以把? extends String理解為任何String或其子類的實(shí)際類型參數(shù)。同樣的,你可以把? super String理解為任何String或其父類的實(shí)際類型參數(shù)。因?yàn)镾tring是final的,這意味著它不能被繼承,只有源列表為String對象,目標(biāo)列表為String或Object對象能夠傳入作為參數(shù),這樣用處不大。

你可以使用泛型方法來完全解決這個(gè)問題,它是一個(gè)有類型實(shí)現(xiàn)參數(shù)的類或接口方法。泛型方法支持下面的語法:

1
2
<formalTypeParameterList> returnType
identifier(parameterList)

泛型方法的形參列表在它的返回類型之前。它包含類型參數(shù)和可選的上界。類型參數(shù)可以作為返回類型使用,并且可以出現(xiàn)在參數(shù)列表中。

清單9展示了怎么定義和調(diào)用泛型copy()方法

Listing 9. GenDemo.java (version 5)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import java.util.ArrayList;
import java.util.List;
 
public class GenDemo
{
   public static void main(String[] args)
   {
      List<Integer> grades = new ArrayList<Integer>();
      Integer[] gradeValues =
      {
         new Integer(96),
         new Integer(95),
         new Integer(27),
         new Integer(100),
         new Integer(43),
         new Integer(68)
      };
      for (int i = 0; i < gradeValues.length; i++)
         grades.add(gradeValues[i]);
      List<Integer> failedGrades = new ArrayList<Integer>();
      copy(grades, failedGrades, new Filter<Integer>()
                                 {
                                    public boolean accept(Integer grade)
                                    {
                                       return grade.intValue() <= 50;
                                    }
                                 });
      for (int i = 0; i < failedGrades.size(); i++)
         System.out.println(failedGrades.get(i));
   }
 
   static <T> void copy(List<T> src, List<T> dest,
Filter<T> filter)
   {
      for (int i = 0; i < src.size(); i++)
         if (filter.accept(src.get(i)))
            dest.add(src.get(i));
   }
}
 
interface Filter<T>
{
   boolean accept(T o);
}

清單9中我定義了一個(gè)<T> void copy(List<T> src, List<T> dest, Filter<T> filter)泛型方法。編譯器注意到srcdestfilter參數(shù)的類型都包含類型參數(shù)T。這意味著在方法調(diào)用中必須傳入同樣的實(shí)際類型參數(shù),而編譯器會在調(diào)用中獲取參數(shù)。

如果你編譯清單9(javac GenDemo.java)并運(yùn)行程序(java GenDemo),你應(yīng)該可以看到下面的輸出:

1
2
27
43

Java語言中關(guān)于泛型最有爭議的是什么?

雖然泛型本身并不具爭議,但它在Java語言中的特殊實(shí)現(xiàn)卻是。泛型是作為消除轉(zhuǎn)換的語法糖的編譯時(shí)特性來實(shí)現(xiàn)的。編譯器會在編譯源碼后丟棄泛型類型或泛型的形參類型列表。這個(gè)“丟棄”行為稱為擦除(erasure)。其他在泛型中關(guān)于擦除的例子包含:在代碼類型不正確時(shí),插入時(shí)可以自動轉(zhuǎn)換為合適的類型;通過上界(例如Object)來替換類型參數(shù)。

更多關(guān)于泛型的討論

泛型不只因?yàn)椴脸鴤涫軤幾h。看一下StackOverflow.com的“為什么我們抱怨Java關(guān)于泛型的實(shí)現(xiàn)很糟糕”主題的討論,包含了通配符很難理解和事實(shí)上泛型并不直接值類型(例如,你不能指定List<int>)。

使用擦除會有下面的幾個(gè)限制:

  • instanceof并不能用于參數(shù)化類型,只有一種情況是例外的。這個(gè)例外就是無界的通配符。例如,你不能指定Set<Shape> shapes = null; if (shapes instanceof ArrayList<Shape>){}。相反,你需要把對instanceof表達(dá)式修改為shapes instanceof ArrayList<?>,這種就是無界的通配符。或者,你可以指定shapes instanceof ArrayList,這使用的是原生類型(通常也是推薦使用的做法)。

  • 編譯器把泛型代碼轉(zhuǎn)換為非泛型代碼,并保存在class文件中。一些開發(fā)人員指出擦除會使得你不能通過反射取得泛型信息,因?yàn)樗鼈儾⒉槐4嬖赾lass文件中。開發(fā)人員Jakob Jenkov在“Java 反射:泛型”中指出一些泛型信息會被保存在class文件中的情況,并且這些信息可以通過反射來訪問。

  • 你不能在創(chuàng)建數(shù)組的表達(dá)式中使用類型參數(shù);例如,elements = new E[size];。如果你這樣做,編譯器會報(bào)告泛型數(shù)組創(chuàng)建錯誤信息。

鑒于擦除的限制,你會奇怪為什么泛型要通過擦除來實(shí)現(xiàn)。原因很簡單:Java編譯器被重構(gòu)來使用擦除,因此泛型代碼可以跟那些非泛型的遺留代碼進(jìn)行交互。沒有這個(gè)向后兼容性,遺留代碼在支持泛型的Java編譯器上編譯時(shí)將會報(bào)錯。

第一部分總結(jié)

Java語言已經(jīng)添加了許多新特性。在這篇文章中,我展示了怎么使用斷言來增強(qiáng)你在代碼正確性上的信心,和如何使用泛型來消除ClassCastException。通過使用斷言和泛型,你可以編寫更可靠的代碼,并且使你的代碼在運(yùn)行時(shí)的錯誤降到最低,當(dāng)然,也減少面對生氣的客戶時(shí)的頭痛了。

Java 5 是Java平臺歷史上的一個(gè)重大發(fā)布,雖然泛型比其他特性都更具爭議,但它卻比其他都更加重要。我的下篇文章將會介紹另外7個(gè)在Java5時(shí)加入的必要的特性:類型安全的枚舉,注解,自動裝箱和拆箱,加強(qiáng)的循環(huán),靜態(tài)引入,可變參數(shù),協(xié)變返回類型。在那之前,下載這篇文章的源代碼,它包含了更多的關(guān)于斷言和泛型的提示和例子。

Jeff Friesen是一個(gè)自由職業(yè)導(dǎo)師和側(cè)重Java和Android的軟件開發(fā)人員。除了為Apress寫Java和Android書籍,Jeff為JavaWorld,informIT,Java.netDevSourceSitePoint寫了大量的關(guān)于Java和其他技術(shù)的文章。你可以通過他在TutorTutor.ca的網(wǎng)站聯(lián)系到他

了解更多主題相關(guān)

下載文章的源代碼
閱讀Angelika Langer的Java Generics FAQs,那里有著大量的關(guān)于Java語言泛型的信息和觀點(diǎn)。

對于想學(xué)習(xí)Java語言和它的備受爭議的特性的,Langer的文章理解閉包的爭論(2008.6 JavaWorld)對比了Java 7語言中的三個(gè)關(guān)于添加閉包和lambda表達(dá)式的初始提議。

可以查看“Java反射:泛型”(Jakob Jenkov, Jenkov.com)關(guān)于泛型反射和某些情況下可以在運(yùn)行時(shí)獲取泛型信息的討論。
Java無痛并發(fā)編程,第一部(2013.6):介紹了Executor框架,同步類型和Java并發(fā)集合包。

Java無痛并發(fā)編程,第二部(2013.8):介紹了鎖,原子變量和fork/join操作,還附加了Java8中關(guān)于java.util.concurrent的修改概述。
跟上Java Date和Time API(2013.4):介紹了Java8的JSR310:Date 和Time API,并且展示了你最有可能使用的java.time系列類的使用。
JavaWorld中更多關(guān)于Java集合框架的文章:
Java集合框架從零開始(1998.11 Dan Becker):這篇文章介紹了集合剛引入java時(shí)的歷史。
Java集合中的省時(shí)習(xí)慣(2013.9 Java Q&A blog):展望未來,Jeff Friesen回答一些當(dāng)前使用Java集合的常見問題。

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

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多