成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

理解Java泛型和通配符,這次再也忘不了了

開發 前端
如果向通配符下界集合中添加元素時,只能添加下屆類的子類。比如例子中的:list3.add(5), list3的通配符是<? super Integer>,說明該集合存放的是Integer或者Integer的子類,我只要向容器中放Integer和它的子類都是成立的。

?前言

泛型機制在項目中一直都在使用,比如在集合中ArrayList<String, String>?, Map<String,String>等,不僅如此,很多源碼中都用到了泛型機制,所以深入學習了解泛型相關機制對于源碼閱讀以及自己代碼編寫有很大的幫助。但是里面很多的機制和特性一直沒有明白,特別是通配符這塊,對于通配符上界、下界每次用每次百度,經常忘記,這次我就做一個總結,加深自己的理解。

泛型介紹和使用

泛型在類定義時不會設置類中的屬性或方法參數的具體類型,而是在類使用時(創建對象)再進行類型的定義。會在編譯期檢查類型是否錯誤, 保證程序的可讀性和安全性。

泛型定義根據實際情況可以分為泛型類和泛型方法:

泛型類

public class Point<T, U> {

private T pointX;

private U pintY;

public Point(T pointX, U pintY) {
this.pointX = pointX;
this.pintY = pintY;
}

public void showPoint() {
System.out.println(pointX);
System.out.println(pintY);
}
}
  • 類中引入類型變量,類型變量指的T, U這些,用尖括號<>括起來, 跟在類名后面。
  • 多個類型變量可以用逗號分隔。
  • 在類中的方法和返回值等地方可以使用類型變量。
  • 類型變量采用大寫形式,要求簡短,一般E表示集合的元素類型,K和V表示key和value等。
  • 泛型類使用:Point<Integer, Double>

泛型方法

public class FxMethod {

public static <T> T getMiddleNumber(T ... numbers) {
return null;
}

public <T, U> void showNumber(T t, U u) {
System.out.println("t = " + t);
System.out.println("u = " + u);;
}
}
  • 方法中引入類型變量,在返回類型前添加<>, 中間放置類型變量,多個類型變量用逗號分隔。
  • 在方法的參數和返回值等位置可以使用類型變量。
  • 泛型方法使用:Integer result = FxMethod.getMiddleNumber(2, 3) 或者 Integer result = FxMethod.<Integer>getMiddleNumber(2, 3)。

類型變量的限定

前面講解了泛型一般定義的兩種方式,其中的類型變量沒有任何限定, 這樣在導致一方面在定義泛型的時候無法使用一些API, 需要強轉,另一方面在使用的時候也容易出錯,那么如何給類型變量添加限定呢?

圖片

  • 只有通過extends關鍵字限定,不能通過super關鍵字。
  • 加了限定以后,就可以直接使用限定類相關的API。
  • 多個限定之間用&符號,比如T extends Number & Comparable。
  • 使用泛型時,只能傳入相應限定的類,比如傳入Point<String, String> 就會報編譯錯誤。

通配符使用

泛型的引入的確解決了很大問題,那它是完美的嗎?

class AnimalWrapper<T extends Animal> {
private T animal;

AnimalWrapper(T animal) {
this.animal = animal;
}

public void eat() {
animal.eat();
}

}

class Animal {
private String name;

public void eat() {
System.out.println("animal eat -----");
}
}

class Cat extends Animal {

@Override
public void eat() {
System.out.println(" cat eat -----");
}
}

定義一個AnimalWrapper?,泛型變量中限定為Animal,如果是下面的測試類,會怎么樣呢?

圖片

會編譯報錯,因為AnimalWrapper并不是AnimalWrapper的子類,不能直接傳入。為了解決個問題,我們引入了通配符,通配符一般是在方法中或者泛型類使用中用到。

圖片

AnimalWrapper<Cat>?可以作為AnimalWrapper<?extends Animal>的子類型,這就是利用通配符帶來的好處。

  • 統配符使用在集合或者方法的參數返回值中。
  • 通配符可以分為無邊界通配符、上邊界通配符和下邊界通配符。

無邊界通配符

通配符無邊界,可以傳入任何類型,沒有限制,相當于Object.

基本語法:

<?>

例子:

public static void printList1(List<?> list) {
for (Object x:list) {
System.out.println(x);
}
}

public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
printList1(list); // ok
List<String> list2 = new ArrayList<>();
list2.add("1");
printList1(list2); // ok


List<?> list3 = list;
// get只能用Object接受,
Object o = list3.get(0);
list3.add(5); // compile error
list3.add(new Object()); // compile error
}

小結:

  • 無邊界通配符相當于Object,任何類型都可以傳入,比如List<Integer> list, List<String> list2。
  • 由于?無法確定是哪種類型,所以只能使用Object類型的變量接收, 比如例子中的: Object o = list3.get(0);
  • 如果是無邊界通配符對應的集合類型,不能添加任何元素。因為無法確定集合存放數據的類型,鬼知道我們要放什么類型才合適啊。

通配符上界

通配符上界,可以限制傳入的類型必須是上界這個類或者是這個類的子類。

基本語法:

<? extends 上界> 
<? extends Number>//可以傳入的實參類型是Number或者Number的子類

例子:

public static void printList1(List<? extends Number> list) {
for (Object x:list) {
System.out.println(x);
}
}


public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
printList1(list); // ok
List<Double> list1 = new ArrayList<>();
list1.add(1.0D);
printList1(list1); // ok
List<String> list2 = new ArrayList<>();
list2.add("1");
printList1(list2); // compile error


List<? extends Number> list3 = list;
// get能用上界
Number o = list3.get(0);
// 不能add
list3.add(5); // compile error
list3.add(new Object()); // compile error

}

小結:

  • 通配符上界? extends A, 表明所有的是A的類或者子類型可以傳入,比如本例中的``Integer和Double都是Number的`子類,String不是。
  • 通配符上界? extends A,確定了類型是A或者是A的子類,那么向集合容器get獲取數據,肯定是它的上界類A,因為其他放的類都是A的子類,比如例子中的Number o = list3.get(0);
  • 如果向通配符上界集合中添加元素時,會失敗。 List<? extends A>, 說明容器可以容納的是A或者A的子類,但A的子類有很多,不確定放哪個,為了安全性,就直接不讓你add,比如例子中的list3.add(5);,5雖然是Number的子類,依然不能add。

通配符下界

通配符下界,可以限制傳入的類型必須是這個類或者是這個類的父類。

基本語法:

<? super 下界> 
<? super Integer>//代表 可以傳入的實參的類型是Integer或者Integer的父類類型

例子:

public static void printList1(List<? super Integer> list) {
for (Object x:list) {
System.out.println(x);
}
}


public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
printList1(list); // ok
List<Double> list1 = new ArrayList<>();
list1.add(1.0D);
printList1(list1); // compile error
List<String> list2 = new ArrayList<>();
list2.add("1");
printList1(list2); // compile error


List<? super Integer> list3 = list;
// 不能用下界接收
Integer o = list3.get(0); // compile error
// 能add
list3.add(5); // ok
list3.add(new Number(5)); // compile error

}
  • 通配符上界? super A, 表明所有的是A的類或者A的父類可以傳入。
  • 通配符上界? super A,確定了類型是A或者是A的父類,那么向集合容器get獲取數據,無法確定是A還是A的某個父類,所以不能get, Integer o = list3.get(0); // compile error,比如例子中用Integer接收,萬一list3中放的是Object類型,就涼涼了。
  • 如果向通配符下界集合中添加元素時,只能添加下屆類的子類。比如例子中的:list3.add(5), list3的通配符是<? super Integer>,說明該集合存放的是Integer或者Integer的子類,我只要向容器中放Integer和它的子類都是成立的。

總結

本文淺談了下泛型和通配符的使用,是自己理解的總結,希望后面的開發過程中不要再去百度了,如果哪里有問題希望大家指正。

責任編輯:武曉燕 來源: JAVA旭陽
相關推薦

2021-06-18 08:25:42

Java泛型通配符

2025-03-03 01:25:00

classnameAPI前端

2013-05-02 09:31:25

程序員

2020-11-30 06:27:35

Java泛型Object

2009-06-11 17:31:27

Java泛型

2009-06-16 11:32:00

Java泛型

2023-04-10 16:34:45

編程Java開發

2023-03-24 15:53:24

JavaJava 泛型開發

2021-07-01 06:47:30

Java泛型泛型擦除

2009-03-17 16:22:13

Java泛型接口

2017-11-14 14:41:11

Java泛型IO

2021-03-28 18:40:02

LinuxWindowsJava

2021-07-09 06:11:37

Java泛型Object類型

2011-07-10 13:45:35

JAVA泛型

2009-08-24 10:29:39

C# 泛型

2024-11-05 09:11:09

TypeScript開發者代碼

2024-04-23 08:23:36

TypeScript泛型Generics

2009-08-24 10:37:27

C# 泛型

2023-10-20 09:04:08

JavaScript語言Java

2009-09-25 10:03:51

Java泛型
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产高清毛片 | 久久久久久久国产 | 日本成人午夜影院 | 99热首页| 中文在线а√在线8 | 一区二区三区欧美 | 亚洲精品福利视频 | 亚洲一区二区在线电影 | 久久久亚洲一区 | 日本精品久久久久久久 | 欧美日韩在线观看一区二区三区 | 91天堂| 久久这里只有 | 国产精品一区二区在线播放 | 国产精品1区 | 国产成人99av超碰超爽 | 欧美国产日韩在线观看 | 久久夜视频 | 久久精品国产一区二区电影 | 91麻豆精品国产91久久久更新资源速度超快 | 久优草| 国产精品福利视频 | 亚洲激情在线观看 | 成人免费网站www网站高清 | 亚洲精品一区二区三区蜜桃久 | 日韩高清www | 福利精品| 中文字幕 亚洲一区 | 成人精品系列 | 国产福利资源 | 中文字幕第一页在线 | 日韩综合 | 成人av看片| 亚洲一区二区国产 | 福利视频网站 | 亚洲在线成人 | 国产精品1区2区3区 一区中文字幕 | 91视频在线看 | 亚洲一区二区三区四区在线观看 | 天天干狠狠操 | 青草青草久热精品视频在线观看 |