成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java? 教程(泛型通配符)

qingshanli1988 / 777人閱讀

泛型通配符

在泛型代碼中,稱為通配符的問(wèn)號(hào)(?)表示未知類型,通配符可用于各種情況:作為參數(shù)、字段或局部變量的類型,有時(shí)作為返回類型(盡管更好的編程實(shí)踐是更加具體),通配符從不用作泛型方法調(diào)用、泛型類實(shí)例創(chuàng)建或超類型的類型參數(shù)。

以下部分更詳細(xì)地討論通配符,包括上界通配符、下界通配符和通配符捕獲。

上界通配符

你可以使用上界通配符來(lái)放寬對(duì)變量的限制,例如,假設(shè)你要編寫一個(gè)適用于List、ListList的方法,你可以通過(guò)使用上界通配符來(lái)實(shí)現(xiàn)這一點(diǎn)。

要聲明一個(gè)上界通配符,請(qǐng)使用通配符("?"),后跟extends關(guān)鍵字,后跟上界,請(qǐng)注意,在此上下文中,extends在一般意義上用于表示“extends”(如在類中)或“implements”(如在接口中)。

要編寫適用于NumberNumber的子類型列表的方法,例如Integer、DoubleFloat,你可以指定List<?extends Number>,List一詞比List更具限制性,因?yàn)榍罢咧黄ヅ?b>Number類型的列表,而后者匹配Number類型或其任何子類的列表。

考慮以下process方法:

public static void process(List list) { /* ... */ }

上界通配符,其中Foo是任何類型,匹配FooFoo的任何子類型,process方法可以像Foo類型一樣訪問(wèn)列表元素:

public static void process(List list) {
    for (Foo elem : list) {
        // ...
    }
}

foreach子句中,elem變量遍歷列表中的每個(gè)元素,現(xiàn)在可以在elem上使用Foo類中定義的任何方法。

sumOfList方法返回列表中數(shù)字的總和:

public static double sumOfList(List list) {
    double s = 0.0;
    for (Number n : list)
        s += n.doubleValue();
    return s;
}

以下代碼使用Integer對(duì)象列表打印sum = 6.0

List li = Arrays.asList(1, 2, 3);
System.out.println("sum = " + sumOfList(li));

Double值列表可以使用相同的sumOfList方法,以下代碼打印sum = 7.0

List ld = Arrays.asList(1.2, 2.3, 3.5);
System.out.println("sum = " + sumOfList(ld));
無(wú)界通配符

使用通配符(?)指定無(wú)界通配符類型,例如List,這稱為未知類型的列表,有兩種情況,無(wú)界通配符是一種有用的方法:

如果你正在編寫可以使用Object類中提供的功能實(shí)現(xiàn)的方法。

當(dāng)代碼使用泛型類中不依賴于類型參數(shù)的方法時(shí),例如,List.sizeList.clear,事實(shí)上,經(jīng)常使用Class,因?yàn)?b>Class中的大多數(shù)方法都不依賴于T。

考慮以下方法,printList

public static void printList(List list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

printList的目標(biāo)是打印任何類型的列表,但它無(wú)法實(shí)現(xiàn)該目標(biāo) — 它只打印一個(gè)Object實(shí)例列表,它不能打印List、List、List等,因?yàn)樗鼈儾皇?b>List的子類型,要編寫通用的printList方法,請(qǐng)使用List

public static void printList(List list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}

因?yàn)閷?duì)于任何具體類型A,ListList的子類型,你可以使用printList打印任何類型的列表:

List li = Arrays.asList(1, 2, 3);
List  ls = Arrays.asList("one", "two", "three");
printList(li);
printList(ls);
在本課程的示例中使用了Arrays.asList方法,此靜態(tài)工廠方法轉(zhuǎn)換指定的數(shù)組并返回固定大小的列表。

重要的是要注意ListList是不一樣的,你可以將ObjectObject的任何子類型插入List,但是你只能在List中插入null,通配符使用指南部分提供了有關(guān)如何確定在給定情況下應(yīng)使用哪種通配符(如果有)的更多信息。

下界通配符

上界通配符部分顯示上界通配符將未知類型限制為該類型的特定類型或子類型,并使用extends關(guān)鍵字表示,以類似的方式,下界通配符將未知類型限制為該類型的特定類型或超類型。

使用通配符(?)表示下界通配符,后跟super關(guān)鍵字,后跟下界:。

你可以指定通配符的上界,也可以指定下界限,但不能同時(shí)指定兩者。

假設(shè)你要編寫一個(gè)將Integer對(duì)象放入列表的方法,為了最大限度地提高靈活性,你希望該方法可以處理ListListList — 任何可以保存Integer值的方法。

要編寫適用于IntegerInteger超類型列表的方法,例如Integer、NumberObject,你可以指定List,List一詞比List更具限制性,因?yàn)榍罢邇H匹配Integer類型的列表,而后者匹配任何類型為Integer的超類型的列表。

以下代碼將數(shù)字1到10添加到列表的末尾:

public static void addNumbers(List list) {
    for (int i = 1; i <= 10; i++) {
        list.add(i);
    }
}
通配符和子類型

如泛型、繼承和子類型中所述,泛型類或接口不相關(guān),僅僅因?yàn)樗麄兊念愋椭g存在關(guān)系,但是,你可以使用通配符在泛型類或接口之間創(chuàng)建關(guān)系。

給定以下兩個(gè)常規(guī)(非泛型)類:

class A { /* ... */ }
class B extends A { /* ... */ }

編寫以下代碼是合理的:

B b = new B();
A a = b;

此示例顯示常規(guī)類的繼承遵循此子類型規(guī)則:如果B擴(kuò)展A,則B類是A類的子類型,此規(guī)則不適用于泛型類型:

List lb = new ArrayList<>();
List la = lb;   // compile-time error

假設(shè)IntegerNumber的子類型,ListList之間的關(guān)系是什么?

雖然IntegerNumber的子類型,但List不是List的子類型,事實(shí)上,這兩種類型不相關(guān),ListList的公共父級(jí)是List

為了在這些類之間創(chuàng)建關(guān)系以便代碼可以通過(guò)List的元素訪問(wèn)Number的方法,請(qǐng)使用上界的通配符:

List intList = new ArrayList<>();
List  numList = intList;  // OK. List is a subtype of List

因?yàn)?b>IntegerNumber的子類型,而numListNumber對(duì)象的列表,所以intListInteger對(duì)象列表)和numList之間現(xiàn)在存在關(guān)系,下圖顯示了使用上界和下界通配符聲明的多個(gè)List類之間的關(guān)系。

上一篇:類型推斷 下一篇:泛型通配符捕獲和Helper方法

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/72943.html

相關(guān)文章

  • Java? 教程(目錄)

    Java? 教程 Java教程是為JDK 8編寫的,本頁(yè)面中描述的示例和實(shí)踐沒(méi)有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語(yǔ)言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個(gè)完整的工作示例和數(shù)十個(gè)課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識(shí)的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購(gòu)買。 入門 介紹Java技術(shù)和安裝Java開發(fā)軟件并使用...

    lifesimple 評(píng)論0 收藏0
  • Java? 教程泛型配符捕獲和Helper方法)

    泛型通配符捕獲和Helper方法 在某些情況下,編譯器會(huì)推斷出通配符的類型,例如,列表可以定義為L(zhǎng)ist,但是在評(píng)估表達(dá)式時(shí),編譯器會(huì)從代碼中推斷出特定類型,此場(chǎng)景稱為通配符捕獲。 在大多數(shù)情況下,你不必?fù)?dān)心通配符捕獲,除非你看到包含短語(yǔ)capture of的錯(cuò)誤消息。 WildcardError示例在編譯時(shí)產(chǎn)生捕獲錯(cuò)誤: import java.util.List; public class ...

    ChristmasBoy 評(píng)論0 收藏0
  • Java? 教程泛型配符使用指南)

    泛型通配符使用指南 學(xué)習(xí)使用泛型編程時(shí)更困惑的一個(gè)方面是確定何時(shí)使用上界通配符以及何時(shí)使用下界通配符,此頁(yè)面提供了設(shè)計(jì)代碼時(shí)要遵循的一些準(zhǔn)則。 對(duì)于本文的討論,將變量看作提供的兩個(gè)功能之一是有幫助的: 一個(gè)In變量 in變量向代碼提供數(shù)據(jù),想象一下帶有兩個(gè)參數(shù)的復(fù)制方法:copy(src, dest),src參數(shù)提供要復(fù)制的數(shù)據(jù),因此它是in參數(shù)。 一個(gè)Out變量 out變量保存數(shù)據(jù)以供其他地方使...

    raledong 評(píng)論0 收藏0
  • Java? 教程泛型的限制)

    泛型的限制 要有效地使用Java泛型,必須考慮以下限制: 無(wú)法使用基元類型實(shí)例化泛型類型 無(wú)法創(chuàng)建類型參數(shù)的實(shí)例 無(wú)法聲明類型為類型參數(shù)的靜態(tài)字段 無(wú)法對(duì)參數(shù)化類型使用強(qiáng)制類型轉(zhuǎn)換或instanceof 無(wú)法創(chuàng)建參數(shù)化類型的數(shù)組 無(wú)法創(chuàng)建、捕獲或拋出參數(shù)化類型的對(duì)象 無(wú)法重載將每個(gè)重載的形式參數(shù)類型擦除為相同原始類型的方法 無(wú)法使用基元類型實(shí)例化泛型類型 考慮以下參數(shù)化類型: class P...

    Bowman_han 評(píng)論0 收藏0
  • Java? 教程泛型、繼承和子類型)

    泛型、繼承和子類型 如你所知,只要類型兼容,就可以將一種類型的對(duì)象分配給另一種類型的對(duì)象,例如,你可以將Integer分配給Object,因?yàn)镺bject是Integer的超類型之一: Object someObject = new Object(); Integer someInteger = new Integer(10); someObject = someInteger; // OK ...

    AaronYuan 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<