国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java - Java泛型之上界下界通配符詳解

Java泛型之上界下界通配符詳解

2021-04-05 13:35JAVA專欄 Java

這篇文章主要介紹了Java泛型之上界下界通配符詳解,學習使用泛型編程時,更令人困惑的一個方面是確定何時使用上限有界通配符以及何時使用下限有界通配符。本文提供一些設計代碼時要遵循的一些準則。,需要的朋友可以參考下

泛型,繼承和子類

如你所知,只要類型兼容,就可以將一種類型的對象分配給另一種類型的對象。例如,你可以指定一個整數一個對象,因為對象是一個整數的超類型:

Object someObject = new Object();
Integer someInteger = new Integer(10);
someObject = someInteger; // 好

在面向對象的術語中,這被稱為“是一種”關系。由于Integer 是一種Object,因此允許賦值。但是Integer也是一種Number,所以下面的代碼也是有效的:

public void someMethod(Number n){/ * ... * /}
someMethod(new Integer(10)); // 好
someMethod(new Double(10.1)); // 好

泛型也是如此。您可以執行泛型類型調用,將Number作為其類型參數傳遞,如果參數與Number兼容,則允許任何后續的add調用:

Box <Number> box = new Box <Number>();
box.add(new Integer(10)); // 好
box.add(new Double(10.1)); // 好

現在考慮以下方法:

public void boxTest(Box <Number> n){/ * ... * /}

它接受什么類型的論據?通過查看其簽名,您可以看到它接受一個類型為Box<Number>的參數。但是,這是什么意思?您是否可以按照您的預期傳遞Box<Integer>或Box<Double>?答案是“否”,因為Box<Integer>和Box<Double>不是Box<Number>的子類型。

這是在使用泛型編程時一個常見的誤解,也是一個需要學習的重要概念。

Box<Integer>不是Box<Number>的子類型,即使Integer是Number的子類型。

注意:給定兩個具體類型 A 和 B(例如,Number和Integer),MyClass<A> 與 MyClass<B>無關,無論 A 和 B 是否相關。MyClass<A> 和 MyClass<B> 的公共父是Object。

有關如何在類型參數相關時在兩個泛型類之間創建類似子類型關系的信息,請參閱下面的通配符和子類型一節。

泛型類和子類型化

您可以通過擴展(extends)泛型類或實現(implements)泛型接口來對其進行子類型化。一個類或接口的類型參數與另一個類或接口的類型參數之間的關系由extends和implements子句確定。

使用Collections類作為示例,ArrayList<E> 實現 List<E>,List<E> 擴展Collection<E>。所以 ArrayList<String>是List<String>的子類型,它是Collection<String>的子類型。只要不改變類型參數,就會在類型之間保留子類型關系。

顯示Collection層次結構示例的圖表:ArrayList<String>是 List<String>的子類型,二者都是Collection<String>的子類型。

現在假設我們想要定義我們自己的列表接口PayloadList,它將可選值泛型類型參數P的與每個元素相關聯。它的聲明可能如下:

interface PayloadList<E,P> extends List<E> {
void setPayload(int index, P val);
...
}

PayloadList的以下參數化是List<String>的子類型:

PayloadList<String,String>
PayloadList<String,Integer>
PayloadList<String,Exception>

PayLoadList層次結構的示意圖:PayloadList<String,String>是List<String>的子類型,它是Collection<String>的子類型。 在PayloadList<String,String>的相同級別是PayloadList <String,Integer>和PayloadList<String,Exceptions>。

通配符和子類型

如 泛型,繼承和子類一節中所述,泛型類之間或接口之間幾乎并不因它們的類型參數而相關。但是,您可以使用通配符在泛型類或接口之間創建關系。

給定以下兩個常規(非泛型)類:

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

編寫以下代碼是合理的:

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

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

List<B> lb = new ArrayList<>();
List<A> la = lb; //編譯時錯誤

鑒于Integer是Number的子類型,List<Integer> 和 List<Number> 之間的關系是什么?

盡管Integer是Number的子類型,但List<Integer>不是List<Number>的子類型,實際上,這兩種類型不相關。List<Number>和 List<Integer> 的公共父是 List<?>。

上界(extends)的通配符與下界(super)通配符

為了在這些類之間創建關系以便代碼可以通過 List<Integer> 的元素訪問Number的方法,請使用上界的通配符:

List<? extends Integer> intList = new ArrayList<>();
List<? extends Number> numList = intList; // OK, List<?extends Integer>是 List< ? extends Number>的子類型

因為Integer是Number的子類型,而numList是Number對象的列表,所以intList(是一個Integer對象列表)和numList之間現在存在關系。下圖顯示了使用上限和下限通配符聲明的多個 List 類之間的關系。

通配符使用指南

學習使用泛型編程時,更令人困惑的一個方面是確定何時使用上限有界通配符以及何時使用下限有界通配符。本文提供一些設計代碼時要遵循的一些準則。

為討論方便,認為變量具備兩個功能:

一個“In”變量

“in”變量向代碼提供數據。想象一下帶有兩個參數的復制方法:copy(src,dest)。該SRC參數提供的數據被復制,因此它是“in”參數。

一個“Out”變量
“out”變量保存數據以供其他地方使用。在復制示例中,copy(src,dest),dest參數接受數據,因此它是“out”參數。

當然,一些變量既用于“in”又用于“out”目的 - 這種情況也在本文中也用到了。

在決定是否使用通配符以及適合使用哪種類型的通配符時,可以使用“in”和“out”原則。以下列表提供了遵循的準則:

通配符指南:

  • 使用extends關鍵字, 定義帶有上界通配符的“in”變量。
  • 使用super關鍵字,使用下界通配符定義“out”變量。
  • 在可以使用Object類中定義的方法訪問“in”變量的情況下,使用無界通配符。
  • 在代碼需要作為“in”和“out”變量訪問變量的情況下,不要使用通配符。

這些指南不適用于方法的返回類型。應該避免使用通配符作為返回類型,因為它強制程序員使用代碼來處理通配符。

List<? extends ...> 可以被非正式地認為是只讀的,但這不是一個嚴格的保證。假設您有以下兩個類:

class NaturalNumber {
private int i;
public NaturalNumber(int i) { this.i = i; }
// ...
}
class EvenNumber extends NaturalNumber {
public EvenNumber(int i) { super(i); }
// ...
}

請考慮以下代碼:

List<EvenNumber> le = new ArrayList<>();
List<? extends NaturalNumber> ln = le;
ln.add(new NaturalNumber(35)); // compile-time error //編譯時錯誤

因為List<EvenNumber>是List<? extends NaturalNumber>,您可以賦值le給ln。但是你不能使用ln將自然數添加到偶數列表中。列表中的以下操作是可能的:

  • 您可以添加null。
  • 你可以調用清除。
  • 您可以獲取迭代器并調用remove。
  • 您可以捕獲通配符并寫入從列表中讀取的元素。

你可以看到List<? extends NaturalNumber>在嚴格意義上不是只讀的,但您可能會這樣想,因為您無法存儲新元素或更改列表中的現有元素。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
  • Javajava springmvc實現驗證碼功能

    java springmvc實現驗證碼功能

    這篇文章主要為大家詳細介紹了java springmvc實現驗證碼功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    qq_3557202011662021-02-20
  • Java關于struts2中Action名字的大小寫問題淺談

    關于struts2中Action名字的大小寫問題淺談

    這篇文章主要給大家介紹了關于struts2中Action名字大小寫問題的相關資料,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小...

    merrick3261402020-11-17
  • Java基于StringBuilder類中的重要方法(介紹)

    基于StringBuilder類中的重要方法(介紹)

    下面小編就為大家帶來一篇基于StringBuilder類中的重要方法(介紹)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    Java教程網1582020-11-29
  • JavaStruts2實現上傳單個文件功能

    Struts2實現上傳單個文件功能

    這篇文章主要為大家詳細介紹了Struts2實現上傳單個文件功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    我扶奶奶過哈登4572020-11-05
  • JavaSpring Boot中利用JavaMailSender發送郵件的方法示例(附源碼)

    Spring Boot中利用JavaMailSender發送郵件的方法示例(附源碼)

    這篇文章主要介紹了Spring Boot中利用JavaMailSender發送郵件的方法示例, 相信使用過Spring的眾多開發者都知道Spring提供了非常好用的JavaMailSender接口實現郵件發...

    翟永超2692020-08-05
  • JavaJava Proxy機制詳細解讀

    Java Proxy機制詳細解讀

    這篇文章主要介紹了Java Proxy機制詳細解讀,還是非常不錯的,這里分享給大家,需要的朋友可以參考下。...

    Santinel4402021-01-17
  • Javajava數據結構之插入排序

    java數據結構之插入排序

    這篇文章主要為大家詳細介紹了java數據結構之插入排序的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    阿木俠6152021-02-02
  • JavaJava中單例模式的7種寫法

    Java中單例模式的7種寫法

    這篇文章主要介紹了Java中單例模式的7種寫法,本文分別給出每種方式的實現代碼,需要的朋友可以參考下 ...

    junjie4382019-12-18
主站蜘蛛池模板: 亚洲精品一区二区三区 | 精品一区二区三区在线观看 | 亚洲精品一区二区三区樱花 | 国产视频一区在线 | 99精品一区二区三区 | 精品久久久久久久久久久久 | 国产成人精品一区二区三区网站观看 | 日韩高清在线 | 国产成人久久 | 国产三级网站 | 青青操天天干 | 国产一区免费视频 | 久久久久一区二区 | 欧美伦理一区二区三区 | 久久精品亚洲精品国产欧美kt∨ | 成人免费淫片aa视频免费 | 不卡视频在线 | 欧美综合一区二区三区 | 亚洲精品免费视频 | 欧美日韩高清不卡 | 成人av播放 | 欧美成人免费在线视频 | 黄色毛片在线看 | 超色视频在线观看 | 欧美 日韩 综合 | 成人精品免费视频 | 97视频免费在线观看 | 四虎新网站 | 操操你 | 久久久久久综合 | 欧美大片免费影院在线观看 | 婷婷激情久久 | 久久综合久久综合久久 | 国产在线视频网站 | 国产午夜精品美女视频明星a级 | 成人综合站 | 中文字幕国产一区 | 午夜视频在线播放 | 日韩欧美在线一区二区 | 国产毛片毛片 | 干片网 |