泛型
1. 認識泛型
定義類、接口、方法時,同時聲明了一個或多個類型變量(如:),稱為泛型類、泛型接口、泛型方法、它們統稱為泛型。
2. 泛型類
public class Test {public static void main(String[] args) {MyArrayList<String> list = new MyArrayList<>();System.out.println(list.add("Jack")); // trueSystem.out.println(list.get(0)); // Jack}
}// 自定義一個泛型類,去模擬 ArrayList
class MyArrayList<E> { // 如果不想規范地寫,其實E也可以寫成其他字母private Object[] arr = new Object[10]; // 容器,用來裝東西private int size; // 記錄當前裝了多少個public boolean add(E content) {arr[size++] = content;return true;}public E get(int index) {return (E) arr[index];}
}
public class Test {public static void main(String[] args) {MyClass<String, String> obj = new MyClass<>();obj.put("只能是String類型", "只能是String類型");
// Others<String> obj1 = new Others<>(); // 報錯Others<MyClass> obj2 = new Others<>(); // 正常System.out.println(obj2.age); // 輸出結果:0}
}class MyClass<E, T> {public void put(E e, T t) {}
}// 要求 E 的類型是繼承 MyClass 或者 E 的類型是 MyClass
class Others<E extends MyClass> {public int age;
}
3. 泛型接口
- 注意:類型變量建議用大寫的英文字母,常用的有:E、T、K、V 等
import java.util.ArrayList;public class Test {public static void main(String[] args) {}
}class Student {}class Teacher {}// 泛型接口
interface Data<E> {void add(E obj);ArrayList<E> getByName(String name);}// 實現類
class StudentData implements Data<Student> {@Overridepublic void add(Student obj) {}@Overridepublic ArrayList<Student> getByName(String name) {return null;}
}// 實現類
class TeacherData implements Data<Teacher> {@Overridepublic void add(Teacher obj) {}@Overridepublic ArrayList<Teacher> getByName(String name) {return null;}
}
4. 泛型方法
案例一
public class Test {public static void main(String[] args) {System.out.println(get(10)); // 10System.out.println(get("Java")); // JavaSystem.out.println(get(new A())); // 對象的內存地址: login.A@3b07d329}// 泛型方法public static <T> T get(T name) {return (T) name;}// 泛型方法public static <E> void run(E index) {}
}class A {}
案例二
通配符:就是" ? ",可以在"使用泛型"的時候代表一切類型;E T K V 是在定義泛型的時候使用
import java.util.ArrayList;public class Test {public static void main(String[] args) {// 需求:實現所有的汽車都能一起參加比賽ArrayList<Car> cars = new ArrayList<>();cars.add(new BMW());cars.add(new BENZ());go(cars);ArrayList<BMW> bmws = new ArrayList<>();bmws.add(new BMW());bmws.add(new BMW());go(bmws);ArrayList<BENZ> benzs = new ArrayList<>();benzs.add(new BENZ());benzs.add(new BENZ());go(benzs);ArrayList<Dog> dogs = new ArrayList<>();dogs.add(new Dog());dogs.add(new Dog());
// go(dogs); // 報錯}// <T>是沒有限制數據類型的泛型,如果我們加一個限制條件,不要讓狗類進來,可以這樣寫:<T extends Cars>,完整代碼如下一行所示public static <T extends Car> void go(ArrayList<T> allCars) {}// 知識擴展:// ? 是通配符,在使用泛型的時候可以代表一切類型" ? extends Car "【上限】 " ? super Car "【下限】
// public static void go1(ArrayList<? extends Car> allCars) {}
// public static void go2(ArrayList<? super Car> allCars) {}
}class Car {}class BMW extends Car {}class BENZ extends Car {}class Dog {}
5. 注意事項
- 泛型是工作在編譯階段的,一旦程序編譯成 class 文件,class 文件中就不存在泛型了,這就是泛型擦除。
- 泛型不支持基本數據類型,只能支持對象類型(引用數據類型)
import java.util.ArrayList;public class Test {public static void main(String[] args) {
// ArrayList<int> list1 = new ArrayList<>(); // 報錯ArrayList<Integer> list2 = new ArrayList<>(); // 正常}
}