引出問題
- 當我們在集合中加入數據的時候想要對數據進行約束。比如:就想傳入自己創建的對象
- 遍歷的時候,需要進行類型轉換,如果結合中的數據量較大,對效率有影響
-
import java.util.*; public class text { public static void main(String[] args) { // ArrayList<Dog> 解釋:如果指定泛型 這個ArrayList集合中只能傳入Dog對象 ArrayList<Dog> AL = new ArrayList<>(); AL.add(new Dog("小黃",3)); //會報錯,因為已經指定ArrayList中傳入的類型了 AL.add(new Cat("小黑",3));//這里會報錯 } } class Dog{ private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } } class Cat{ private String name; private int age; public Cat(String name, int age) { this.name = name; this.age = age; } }
泛型的好處
- 編譯時,可以檢查添加數據的類型,提高了安全性
- 減少了類型轉化的次數,提高效率
泛型的注意事項
- 泛型只能是引用數據類型:Integer✅ int ❌
- 再給泛型指定具體類型后,可以傳入該類型或繼承該類型的子類
- 指定泛型可以是接口類型
自定義泛型(創建自己的類,自己定義泛型)
- 基本語法:class 類名<T , R , ..> { 成員 }
-
public class text { public static void main(String[] args) { //當創建對象了,指定了 T 是Integer R是 String Dog<Integer, String> dog = new Dog<>(); } } class Dog<T,R>{ String name; //以下表示正確,需要在創建的時候指定類型 T age; R gender; public String getName() { return name; } public void setName(String name) { this.name = name; } public T getAge(R r) {//方法返回值可以是自定義泛型,形參也可以是泛型 return age; } public void setAge(T age) { this.age = age; } public R getGender() { return gender; } public void setGender(R gender) { this.gender = gender; } }
- 如果在創建是不指定 T 和 R 的類型 ,默認是Object
- 普通成員可以使用泛型(屬性,方法)
- 使用泛型數組不能初始化,T[ ] t = new [8] ❌。 因為類型不確定,不知道開多大空間
- 靜態方法不能使用泛型,靜態屬性同樣,因為靜態是和類相關的,在類加載時,對象還沒有創建
泛型的繼承和通配符
泛型不具備繼承性。例如:List< Object > list = new ArrayList<String>( ); ❌ 錯誤,不具備繼承
< ? >可以接受任意泛型類型
< ? extends AA>:表示可以接受AA類,或AA子類類型
< ? super AA>:表示可以接受AA類,和AA類的父類,Object也可以