中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java generic中通配符的理解有哪些

發布時間:2021-10-29 10:28:30 來源:億速云 閱讀:142 作者:柒染 欄目:編程語言

本篇文章給大家分享的是有關Java generic中通配符的理解有哪些,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

置換原則

結合Java本身的一些面向對象的特性,我們很容易理解這么一個置換原則:

一個指定類型的變量可以被賦值為該類型的任何子類;一個指定某種類型參數的方法可以通過傳入該類型的子類來進行調用。

總的來說,就是說我們使用的任何類型變量都可以用該類型的子類型來替換。

泛型中一種錯誤的繼承關系

在泛型的編程中,我們考慮到子類型關系的時候,容易把一種關系給弄混淆,并錯誤的采用置換原則。

比如說:

List<Integer> ints = new ArrayList<Integer>();  ints.add(1);  ints.add(2);  List<Number> nums = ints; // compile error

在這段代碼中,我們看到類型參數Integer是Number的子類型,就容易想當然的認為List<Integer>也是List<Number>的子類。實際上并不是。所以才會導致類型不匹配,產生編譯時錯誤。

有點時候,我們覺得,這樣的轉換看似不能用到一個好處,就是利用對象之間繼承的關系。要是我們能有一個列表,它既能處理某種類型的數據,還能處理該類型的所有子類型的數據,這樣豈不是既能用到泛型的好處又可以用到對象關系的好處么?于是在這里就引出了通配符(wildcard)。

通配符(Wildcard)

在Java類庫中Collection接口定義中有一個用到通配符的方法:

interface Collection<E> {  ...  public boolean addAll(Collection<? extends E> c);  ...  }

在addAll方法的描述里,可以接受Collection類型的參數。其中Collection中的類型參數可以為任何繼承E的子類型。

因此,我們可以在實際代碼中這么使用:

List<Number> nums = new ArrayList<Number>();  List<Integer> ints = Arrays.asList(1, 2);  List<Double> dbls = Arrays.asList(2.78, 3.14);  nums.addAll(ints);  nums.addAll(dbls);

在代碼中我們可以看到,List<Integer>和List<Double>都是Collection<? extends Number>類型的子類。所以上面的方法中可以將Integer和Double兩種類型的List傳入到方法中。

通配符使用限制1:

使用通配符的泛型數據類型比較有意思,既然前面我們可以將其作為方法聲明的參數,那么是否可以將它作為一個變量類型來直接創建變量呢?

看如下代碼:

List<? extends Number> nums = new ArrayList<Integer>(); //compile error

實際上上面這段代碼是編譯通不過的。

通配符使用限制2:

既然不能用來直接創建變量對象,那么再看下面這段代碼:

List<Integer> ints = new ArrayList<Integer>();  ints.add(1);  ints.add(2);  List<? extends Number> nums = ints;  nums.add(3.14); // compile error

這段代碼的第5行會導致編譯錯誤。在第4行代碼中,我們將ints賦值給nums,表面上nums聲明為一個List<Integer>的父類型,所以第4行編譯正常。為什么第5行代碼會出錯呢?表面上看來,既然nums類型可以接受繼承自Number的所有參數,那加一個Double類型的數據應該是沒問題的。實際上我們再考慮一下這樣會帶來的問題:

nums本來引用的是一個繼承自該類型的List<Integer>,如果我們允許加入Double類型的數據的話,那么ints這個Integer的List里面就包含了Double的數據,當我們使用ints的時候,和我們所期望的只包含Integer類型的數據不符合。

因此,這段代碼也說明了一個問題,就是在? extends E這種通配符引用的數據類型中,如果向其中增加數據操作的話會有問題。所以向其中增加數據是不允許的。但是我們可以從其中來讀取數據。

總結:

1:通配符修飾的泛型不能用來直接創建變量對象。

2:通配符修飾相當于聲明了一種變量,它可以作為參數在方法中傳遞。這么做帶來的好處就是我們可以將應用于包含某些數據類型的列表的方法也應用到包含其子類型的列表中。相當于可以在列表中用到一些面向對象的特性。

以上就是Java generic中通配符的理解有哪些,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

嵩明县| 三明市| 奎屯市| 夏津县| 东丽区| 克什克腾旗| 朝阳县| 玉田县| 宜宾市| 分宜县| 五家渠市| 泾川县| 靖西县| 岳西县| 屯留县| 贵阳市| 长海县| 旺苍县| 霍林郭勒市| 梁河县| 根河市| 金溪县| 莱芜市| 富川| 朝阳区| 汕头市| 方山县| 嘉黎县| 仙游县| 涪陵区| 大竹县| 泸水县| 临沭县| 通海县| 华宁县| 名山县| 榆林市| 库车县| 青浦区| 循化| 湘西|