日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java泛型程序设计——通配符类型+通配符的超类型限定

發布時間:2023/12/3 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java泛型程序设计——通配符类型+通配符的超类型限定 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【0】README

0.1) 本文描述+源代碼均 轉自 core java volume 1, 旨在理解 java泛型程序設計 的 通配符類型+通配符的超類型限定 的知識;


【1】通配符類型相關

1.1)通配符類型: Pair < ? extends Employee> 表示任何泛型Pair 類型, 它的類型參數是 Employee的子類 , 如 Pair , 但不是 Pair
1.2)問題+解決方法:

  • 1.2.1)問題:假設要編寫一個打印雇員對的方法, 如
public static void printBuddies(Pair<Employee> p) {Employee first = p.getFirst();Employee second = p.getSecond();System.out.println(first.getName() + second.getName()); }
  • 正如前面講到的, 不能將 Pair< Manager > 傳遞給這個方法, 這一點很受限制, 因為 Pair< Manager > 不是 Pair< Employee > 的子類, 它們兩個根本就沒有半毛錢關系的
  • 1.2.2)解決方法:使用通配符類型:
public static void printBuddies(Pair<? extends Employee> p)
  • 因為 類型 Pair< Manager>是 Pair< ? extends Employee> 的 子類型;如下圖:

1.3)使用通配符會通過Pair< ? extends Employee > 的引用破壞Pair< Manger >嗎?

  • 1.3.1)看個荔枝:
Pair<Manager> m = new Pair<>(ceo, cfo); Pair<? extends Employee> m2 = m1; //OK m2.setFirst(lowlyEmployee); // compile-time error
  • 1.3.2) 這可能不會引起破壞。 對 setFirst的調用有一個類型錯誤。 要了解其中的緣由, 請仔細看一看類型 Pair< ? extends Employee > , 其方法似乎是這樣的:
? extends Employee getFirst() void setFirst(? extends Employee)
  • 1.3.3)這樣將不可能調用 setFirst 方法。 編譯器只知道 需要某個 Employee 的子類型, 但不知道具體是 什么類型。 它拒絕傳遞任何特定的類型, 畢竟? 不能用來匹配;
  • 1.3.4)使用 getFirst 就不存在這個問題:將 getFirst 的返回值賦給一個 Employee 的引用完全合法。 這就是引入有限定的通配符的關鍵之處;

【2】通配符的超類型限定

2.1)超類型限定, 如下所示:

? super Manager 這個通配符限制為 Manager 的所有超類型。
  • 2.1.1)為什么要這樣做呢? 帶有超類型的通配符行為可以為 方法提供參數, 但不能使用 返回值;
如, Pair<? super Manger> 有方法 void setFirst(? super Manager) ? super Manger getFirst();
  • 編譯器不知道setFirst 方法的確切類型, 但是可以用任意Manger對象調用它, 而不能用 Employee對象調用。 然而, 如果調用 getFirst , 返回的對象類型就不會得到保證, 只能吧它賦給一個 Object;

2.2)看個荔枝: 有一個經理的數組,并且想把 獎金最高和最低的經理放在一個 Pair 對象中。

  • 2.2.1)Pair 的類型是什么? 在這里 , Pair< Employee >是合理的, Pair< Object > 也是合理的, 下面的方法將可以接收任何適當的Pair;

2.3)干貨總結: 直觀地講,帶有超類型限定的通配符可以向泛型對象寫入, 帶有子類型限定的通配符可以從泛型對象讀取;

  • 2.3.1)看個荔枝: 下面是超類型限定的另一種應用。 Comparable接口本身就是一個泛型類型,如下:
public interface Comparable<T> {public int compareTo(T other); }
  • 2.3.2) 由于 Comparable是一個泛型類型, 也許可以吧 ArrayAlg 類的min 方法做的更好一些?可以這樣聲明:
public static <T extends Comparable<T>> T min(T[] a)
  • 看起來, 這樣寫比只使用T extends Comparable 更徹底, 并且對于許多類來講, 工作得更好。例如, 如果計算一個String 數組的最小值, T就是String 類型的, 而 String 是 Comparable< String > 的子類型。
  • 2.3.3)出現的問題: 當處理一個Gregorian Calender 對象的數組時, 就會出現問題:

    • GregorianCalendar 是 Calendar 的子類, 并且 Calendar 實現了 Comparable< Calendar> , 因此 GregorianCalendar實現的是Comparable< Calendar>, 而不是 Comparable< GregorianCalendar>;
  • 2.3.4)解決方法(使用超類型):

public static <T extends Comparable<? super T>> T min(T[] a)
  • 現在compareTo 方法寫成: int compareTo(? super T)
  • 有可能被聲明為 使用類型T的對象, 也有可能使用T 的超類型(如當T是 GregorianCalendar), 無論如何, 傳遞一個 T 類型的對象給 compareTo 方法都是安全的;

Conclusion)

  • C1)對于新手來說, < T extends Comparable< ? super T>> 這樣的聲明看起來有點嚇人;
  • C2)因為, 這一聲明的意圖在于幫助應用程序員排除調用參數上的不必要的限制;
  • C3)對泛型沒有興趣的coders 很可能很快就學會掩蓋這些聲明了, 想當然地認為庫程序員做的都是正確的;
  • C4)如果是一名庫程序員, 一定要習慣于通配符, 否則, 就會受到用戶的責備, 還要在代碼中隨意地添加強制類型轉換直到代碼可以編譯;

總結

以上是生活随笔為你收集整理的java泛型程序设计——通配符类型+通配符的超类型限定的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。