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

資訊專欄INFORMATION COLUMN

Java? 教程(類型推斷)

JerryC / 2827人閱讀

類型推斷

類型推斷是Java編譯器查看每個方法調(diào)用和相應(yīng)聲明的能力,以確定使調(diào)用適用的類型參數(shù),推理算法確定參數(shù)的類型,如果可用,還確定分配或返回結(jié)果的類型,最后,推理算法嘗試查找適用于所有參數(shù)的最具體類型。

為了說明最后一點(diǎn),在下面的示例中,推斷確定傳遞給pick方法的第二個參數(shù)是Serializable類型:

static  T pick(T a1, T a2) { return a2; }
Serializable s = pick("d", new ArrayList());
類型推斷和泛型方法

泛型方法向你介紹了類型推斷,它使你能夠像普通方法一樣調(diào)用泛型方法,而無需在尖括號之間指定類型,考慮以下示例BoxDemo,它需要Box類:

public class BoxDemo {

  public static  void addBox(U u, 
      java.util.List> boxes) {
    Box box = new Box<>();
    box.set(u);
    boxes.add(box);
  }

  public static  void outputBoxes(java.util.List> boxes) {
    int counter = 0;
    for (Box box: boxes) {
      U boxContents = box.get();
      System.out.println("Box #" + counter + " contains [" +
             boxContents.toString() + "]");
      counter++;
    }
  }

  public static void main(String[] args) {
    java.util.ArrayList> listOfIntegerBoxes =
      new java.util.ArrayList<>();
    BoxDemo.addBox(Integer.valueOf(10), listOfIntegerBoxes);
    BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);
    BoxDemo.addBox(Integer.valueOf(30), listOfIntegerBoxes);
    BoxDemo.outputBoxes(listOfIntegerBoxes);
  }
}

以下是此示例的輸出:

Box #0 contains [10]
Box #1 contains [20]
Box #2 contains [30]

泛型方法addBox定義了一個名為U的類型參數(shù),通常,Java編譯器可以推斷泛型方法調(diào)用的類型參數(shù),因此,在大多數(shù)情況下,你不必指定它們,例如,要調(diào)用泛型方法addBox,可以使用類型見證指定類型參數(shù),如下所示:

BoxDemo.addBox(Integer.valueOf(10), listOfIntegerBoxes);

或者,如果省略類型見證,Java編譯器會自動推斷(從方法的參數(shù))類型參數(shù)是Integer

BoxDemo.addBox(Integer.valueOf(20), listOfIntegerBoxes);
類型推斷和泛型類的實例化

只要編譯器可以從上下文中推斷出類型參數(shù),就可以用一組空的類型參數(shù)(<>)替換調(diào)用泛型類的構(gòu)造函數(shù)所需的類型參數(shù),這對尖括號被非正式地稱為菱形。

例如,請考慮以下變量聲明:

Map> myMap = new HashMap>();

你可以使用一組空的類型參數(shù)(<>)替換構(gòu)造函數(shù)的參數(shù)化類型:

Map> myMap = new HashMap<>();

請注意,要在泛型類實例化期間利用類型推斷,必須使用菱形,在以下示例中,編譯器生成未經(jīng)檢查的轉(zhuǎn)換警告,因為HashMap()構(gòu)造函數(shù)引用HashMap原始類型,而不是Map>類型:

Map> myMap = new HashMap(); // unchecked conversion warning
類型推斷和泛型與非泛型類的泛型構(gòu)造函數(shù)

請注意,構(gòu)造函數(shù)在泛型和非泛型類中都可以是泛型的(換句話說,聲明它們自己的形式類型參數(shù)),考慮以下示例:

class MyClass {
   MyClass(T t) {
    // ...
  }
}

考慮以下MyClass類的實例化:

new MyClass("")

此語句創(chuàng)建參數(shù)化類型MyClass的實例,該語句顯式指定泛型類MyClass的形式類型參數(shù)X的類型Integer,請注意,此泛型類的構(gòu)造函數(shù)包含形式類型參數(shù)T,編譯器為此泛型類的構(gòu)造函數(shù)的形式類型參數(shù)T推斷類型String(因為此構(gòu)造函數(shù)的實際參數(shù)是String對象)。

Java SE 7之前版本的編譯器能夠推斷泛型構(gòu)造函數(shù)的實際類型參數(shù),類似于泛型方法,但是,如果使用菱形(<>),Java SE 7及更高版本中的編譯器可以推斷出要實例化的泛型類的實際類型參數(shù),考慮以下示例:

MyClass myObject = new MyClass<>("");

在此示例中,編譯器為泛型類MyClass的形式類型參數(shù)X推斷類型Integer,它推斷出此泛型類的構(gòu)造函數(shù)的形式類型參數(shù)T的類型String。

值得注意的是,推理算法僅使用調(diào)用參數(shù)、目標(biāo)類型以及可能明顯的預(yù)期返回類型來推斷類型,推理算法不使用程序后面的結(jié)果。
目標(biāo)類型

Java編譯器利用目標(biāo)類型來推斷泛型方法調(diào)用的類型參數(shù),表達(dá)式的目標(biāo)類型是Java編譯器所期望的數(shù)據(jù)類型,具體取決于表達(dá)式的顯示位置,考慮方法Collections.emptyList,聲明如下:

static  List emptyList();

考慮以下賦值語句:

List listOne = Collections.emptyList();

此語句期望List的實例,此數(shù)據(jù)類型是目標(biāo)類型,因為方法emptyList返回List類型的值,所以編譯器推斷類型參數(shù)T必須是值String,這適用于Java SE 7和8,或者,你可以使用類型見證并指定T的值,如下所示:

List listOne = Collections.emptyList();

但是,在這種情況下,這不是必需的,不過,在其他情況下這是必要的,考慮以下方法:

void processStringList(List stringList) {
    // process stringList
}

假設(shè)你要使用空列表調(diào)用方法processStringList,在Java SE 7中,以下語句不編譯:

processStringList(Collections.emptyList());

Java SE 7編譯器生成類似于以下內(nèi)容的錯誤消息:

List cannot be converted to List

編譯器需要類型參數(shù)T的值,因此它以值Object開始,因此,Collections.emptyList的調(diào)用返回List類型的值,該值與方法processStringList不兼容,因此,在Java SE 7中,你必須指定類型參數(shù)值的值,如下所示:

processStringList(Collections.emptyList());

Java SE 8中不再需要這樣做,什么是目標(biāo)類型的概念已經(jīng)擴(kuò)展為包括方法參數(shù),例如方法processStringList的參數(shù),在這種情況下,processStringList需要一個List類型的參數(shù),方法Collections.emptyList返回List的值,因此使用List的目標(biāo)類型,編譯器推斷類型參數(shù)T的值為String,因此,在Java SE 8中,以下語句編譯:

processStringList(Collections.emptyList());

有關(guān)詳細(xì)信息,請參閱Lambda表達(dá)式中的目標(biāo)類型。

上一篇:泛型、繼承和子類型 下一篇:泛型通配符

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

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

相關(guān)文章

  • Java? 教程(泛型類型

    泛型類型 泛型類型是通過類型參數(shù)化的泛型類或接口,修改以下Box類以演示此概念。 一個簡單的Box類 首先檢查一個對任何類型的對象進(jìn)行操作的非泛型Box類,它只需要提供兩個方法:set,它將一個對象添加到box中,get,它將檢索它: public class Box { private Object object; public void set(Object object) ...

    Crazy_Coder 評論0 收藏0
  • Java 10 實戰(zhàn)第 1 篇:局部變量類型推斷

    摘要:就等于局部變量類型推斷使用示例既然叫局部變量類型推斷,以只能用在局部變量中,下面給出更多使用示例。,本次局部變量類型推斷實戰(zhàn)文章就到這里了,后續(xù)帶來更多的的實戰(zhàn)方面的文章。 現(xiàn)在 Java 9 被遺棄了直接升級到了 Java 10,之前也發(fā)過 Java 10 新特性的文章,現(xiàn)在是開始實戰(zhàn) Java 10 的時候了。 今天要實戰(zhàn)的是 Java 10 中最重要的特性:局部變量類型推斷,大家...

    HollisChuang 評論0 收藏0
  • Java? 教程(泛型通配符捕獲和Helper方法)

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

    ChristmasBoy 評論0 收藏0
  • Java? 教程(泛型方法)

    泛型方法 泛型方法是引入其自己的類型參數(shù)的方法,這類似于聲明泛型類型,但類型參數(shù)的范圍僅限于聲明它的方法,允許使用靜態(tài)和非靜態(tài)泛型方法,以及泛型類構(gòu)造函數(shù)。 泛型方法的語法包括類型參數(shù)列表,在尖括號內(nèi),它出現(xiàn)在方法的返回類型之前,對于靜態(tài)泛型方法,類型參數(shù)部分必須出現(xiàn)在方法的返回類型之前。 Util類包含一個泛型方法compare,它比較兩個Pair對象: public class Util { ...

    PingCAP 評論0 收藏0
  • Java 11 教程

    摘要:原文鏈接已于成功發(fā)布,不過目前絕大多數(shù)人在生產(chǎn)環(huán)境仍舊使用的是。這篇以案例為主的教程涵蓋了從到的絕大多數(shù)重要的語法與特性。當(dāng)編譯器不能正確識別出變量的數(shù)值類型時,將不被允許使用。同步請求將會阻塞當(dāng)前的線程,直到返回響應(yīng)消息。 showImg(https://segmentfault.com/img/remote/1460000016575203); 原文鏈接:https://wangw...

    douzifly 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<