第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

何時(shí)使用通用方法,何時(shí)使用通配符?

何時(shí)使用通用方法,何時(shí)使用通配符?

瀟湘沐 2019-07-06 14:29:05
何時(shí)使用通用方法,何時(shí)使用通配符?我正在閱讀關(guān)于泛型方法的文章。OracleDocGenericMethod..當(dāng)它說(shuō)明何時(shí)使用通配符和何時(shí)使用泛型方法時(shí),我對(duì)這種比較感到非常困惑。引用文件中的話。interface Collection<E> {     public boolean containsAll(Collection<?> c);     public boolean addAll(Collection<? extends E> c);}我們本可以在這里使用通用方法,而不是:interface Collection<E> {     public <T> boolean containsAll(Collection<T> c);     public <T extends E> boolean addAll(Collection<T> c);     // Hey, type variables can have bounds too!}[…]這告訴我們,類型參數(shù)用于多態(tài)性;它的唯一效果是允許在不同的調(diào)用站點(diǎn)上使用各種實(shí)際的參數(shù)類型。如果是這樣的話,應(yīng)該使用通配符。通配符是為了支持靈活的子類型而設(shè)計(jì)的,這正是我們?cè)谶@里試圖表達(dá)的。我們不覺(jué)得不像(Collection<? extends E> c);是否也支持某種多態(tài)性?那么,為什么在這種情況下泛型方法的使用被認(rèn)為是不好的呢?繼續(xù)向前,它說(shuō),泛型方法允許使用類型參數(shù)來(lái)表示方法和/或其返回類型的一個(gè)或多個(gè)參數(shù)類型之間的依賴關(guān)系。如果不存在這種依賴關(guān)系,則不應(yīng)該使用泛型方法。這是什么意思?他們給出了這個(gè)例子class Collections {     public static <T> void copy(List<T> dest, List<? extends T> src) {     ...}[…]我們可以用另一種方式編寫(xiě)此方法的簽名,而無(wú)需使用通配符:class Collections {     public static <T, S extends T> void copy(List<T> dest, List<S> src) {     ...}文檔阻止第二個(gè)聲明并促進(jìn)第一個(gè)語(yǔ)法的使用?第一次聲明和第二次聲明有什么區(qū)別??jī)扇怂坪醵荚谧鐾瑯拥氖拢坑腥四芙o這個(gè)地區(qū)開(kāi)個(gè)燈嗎。
查看完整描述

3 回答

?
HUWWW

TA貢獻(xiàn)1874條經(jīng)驗(yàn) 獲得超12個(gè)贊

在某些地方,通配符和類型參數(shù)會(huì)做同樣的事情。但也有一些地方,您必須使用類型參數(shù)。

  1. 如果要對(duì)不同類型的方法參數(shù)強(qiáng)制執(zhí)行某種關(guān)系,則不能使用通配符,必須使用類型參數(shù)。

以您的方法為例,假設(shè)您希望確保srcdest傳遞給copy()方法應(yīng)該是相同的參數(shù)化類型,您可以使用類型參數(shù)這樣做:

public static <T extends Number> void copy(List<T> dest, List<T> src)

在這里,你可以確保destsrc具有相同的參數(shù)化類型List..所以,可以安全地從srcdest.

但是,如果您繼續(xù)更改方法以使用通配符:

public static void copy(List<? extends Number> dest, List<? extends Number> src)

它不會(huì)像預(yù)期的那樣起作用。在第二種情況下,你可以通過(guò)List<Integer>List<Float>destsrc..因此,將元素從srcdest不會(huì)再安全了。如果您不需要這樣的關(guān)系,那么您可以完全不使用類型參數(shù)。

使用通配符和類型參數(shù)之間的其他區(qū)別是:

  • 如果只有一個(gè)參數(shù)化類型參數(shù),則可以使用通配符,盡管類型參數(shù)也會(huì)工作。
  • 類型參數(shù)支持多個(gè)邊界,通配符不支持。
  • 通配符支持上下界,類型參數(shù)只支持上界。因此,如果您想要定義一個(gè)采用List類型Integer或者是超級(jí)班,你可以:

    public void print(List<? super Integer> list)  // OK

    但是不能使用類型參數(shù):

     public <T super Integer> void print(List<T> list)  // Won't compile

參考資料:


查看完整回答
反對(duì) 回復(fù) 2019-07-06
?
四季花海

TA貢獻(xiàn)1811條經(jīng)驗(yàn) 獲得超5個(gè)贊

考慮以下由JamesGosling第4版編寫(xiě)的Java編程示例,在下面我們要合并2 SinglyLinkQueue:

public static <T1, T2 extends T1> void merge(SinglyLinkQueue<T1> d, SinglyLinkQueue<T2> s){
    // merge s element into d}public static <T> void merge(SinglyLinkQueue<T> d, SinglyLinkQueue<? extends T> s){
        // merge s element into d}

上述兩種方法都具有相同的功能。那么哪個(gè)更好呢?答案是第二。用作者自己的話說(shuō):

“一般規(guī)則是在可能時(shí)使用通配符,因?yàn)橥ㄅ浞a通常比具有多個(gè)類型參數(shù)的代碼更具可讀性。在決定是否需要類型變量時(shí),問(wèn)問(wèn)自己該類型變量是否用于關(guān)聯(lián)兩個(gè)或多個(gè)參數(shù),還是將參數(shù)類型與返回類型相關(guān)聯(lián)。如果答案是否定的,那么通配符就足夠了?!?/strong>

注意:書(shū)中只給出了第二種方法,類型參數(shù)名為S而不是‘T’。第一種方法不在書(shū)中。


查看完整回答
反對(duì) 回復(fù) 2019-07-06
?
冉冉說(shuō)

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個(gè)贊

在第一個(gè)問(wèn)題中:這意味著如果參數(shù)的類型與方法的返回類型之間存在關(guān)系,那么使用泛型。

例如:

public <T> T giveMeMaximum(Collection<T> items);public <T> Collection<T> applyFilter(Collection<T> items);

在這里,您將按照一定的標(biāo)準(zhǔn)提取一些T。如果T是Long您的方法將返回LongCollection<Long>實(shí)際返回類型取決于參數(shù)類型,因此使用泛型類型是有用的,并建議使用泛型類型。

如果不是這種情況,可以使用通配符類型:

public int count(Collection<?> items);public boolean containsDuplicate(Collection<?> items);

在這兩個(gè)示例中,無(wú)論集合中的項(xiàng)的類型是什么,返回類型都是intboolean.

在你們的例子中:

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

這兩個(gè)函數(shù)將返回一個(gè)布爾值,不管集合中項(xiàng)的類型如何。在第二種情況下,它僅限于E.

第二個(gè)問(wèn)題:

class Collections {
    public static <T> void copy(List<T> dest, List<? extends T> src) {
    ...}

這第一段代碼允許您傳遞一個(gè)異構(gòu)代碼。List<? extends T> src作為參數(shù)。這個(gè)列表可以包含不同類的多個(gè)元素,只要它們都擴(kuò)展了基類T。

如果你有:

interface Fruit{}

class Apple implements Fruit{}class Pear implements Fruit{}class Tomato implements Fruit{}

你可以

List<? extends Fruit> basket = new ArrayList<? extends Fruit>();basket.add(new Apple());basket.add(new Pear());
basket.add(new Tomato());List<Fruit> fridge = new ArrayList<Fruit>(); Collections.copy(fridge, basket);// works

另一方面

class Collections {
    public static <T, S extends T> void copy(List<T> dest, List<S> src) {
    ...}

約束List<S> src作為一個(gè)特殊的類S,它是T的一個(gè)子類,列表只能包含一個(gè)類的元素(在本例中是S),而不能包含其他類的元素,即使它們也實(shí)現(xiàn)了T。您將無(wú)法使用我前面的示例,但您可以這樣做:

List<Apple> basket = new ArrayList<Apple>();basket.add(new Apple());basket.add(new Apple());basket.add(new Apple());
List<Fruit> fridge = new ArrayList<Fruit>();Collections.copy(fridge, basket);
/* works since the basket is defined as a List of apples and not a list of some fruits. */


查看完整回答
反對(duì) 回復(fù) 2019-07-06
  • 3 回答
  • 0 關(guān)注
  • 507 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)