理解Java泛型 通配符 ? 以及其使用
阿新 • • 發佈:2017-07-25
結構 及其 對象 col () 引用變量 .get pub 同時
什麽是泛型:
泛型從字面上理解,是指一個類、接口或方法支持多種類型,使之廣泛化、一般化和更加通用。Java中使用Object類來定義類型也 能實現泛型,但缺點是造成原類型信息的丟失,在使用中容易造成ClassCastException。
Java泛型帶到的好處:
- 使得一個類或方法中的類型參數化,最終達到代碼復用的效果。( 不使用泛型,你可能需要每種情況的類或方法都要定義一遍 )
- 實現類型檢查的功能,避免ClassCastException。(這是相對於使用Object類型實現泛型而言。因為我可以每個類都定義一遍來實現所謂的類型檢查。)
泛型自定義:類、接口、方法
//定義泛型類,接口的定義和類一樣class G1<T> { T content; } // 定義泛型方法,方法的頭部使用<T>聲明,註意結構 class GMethod1 { // 一般泛型方法定義 public static <T> void method1(T params) { } // 返回值也為泛型 public static <E> E method2(E params) { E content = params; return content; } } // extends 的使用,限定泛型的範圍,等於或者是extends的子類class G2<T extends Number> { T content; }
泛型的使用
//泛型類或接口的使用 List<String> list = new ArrayList<>(); //泛型方法的使用,在方法前面使用<>傳入類型 <String>gMethod1.method1("str"); <Integer>gMethod1.method1(new Integer(1)); //如果入參的參數中使用了T,則可以省略方法前面的<>,編譯器可以自行識別出其類型gMethod1.method1("str"); gMethod1.method1(new Integer(1));
通配符?
什麽時候會用通配符:
通配符只有在修飾一個變量時會用到,使用它可方便地引用包含了多種類型的泛型;
public static void main() { //不使用通配符 ArrayList<Object> arr = new ArrayList<Object>(); // ArrayList<Object> arr = new ArrayList<String>(); 編譯不通過,arr只能引用包含Object的集合 //使用通配符 ArrayList<?> arr2; arr2 = new ArrayList<String>(); arr2 = new ArrayList<Integer>(); arr2.get(0); //返回的,是一個Object對象,通配符會使原集合包含類型信息丟失,也是通配符的使用代價 // 通常在方法參數中才會使用通配符,使得這個方法可以引用多種泛型集合。這個和範型方法不一樣,這裏只是一個引用變量 void gMethod(ArrayList<? extends Number> param) { }
可以看到,通配符使用方便的同時,使原集合包含類型信息丟失。
通配符的extends super關鍵字
和定義泛型中的extend概念完全不一樣,這裏有它自己的含義
ArrayList<? extends Number> arr3; // Number 是 Integer、Float的父類 arr3 = new ArrayList<Integer>(); arr3 = new ArrayList<Float>(); // arr3 = new ArrayList<String>(); 編譯不通過,String 和 Number不存在繼承關系 arr3.get(0); //返回的,是一個Number對象 arr3.add(null); //使用過通配符修飾的集合變量,只能add(null),因為這個集合中包含的類型已經確定,只是類型信息已經丟失了,add(Object)也不行
擴展:不使用泛型的變量和另一種方式
//這樣使用功能和通配符一樣,可以多種引用,但一般不推薦這樣使用 ArrayList a4; a4 = new ArrayList<String>(); a4 = new ArrayList<Integer>(); a4.add(new Integer(1)); a4.add(new String("str"));//和通配符引用不能add不一樣,這樣方式可以add多種類型元素,但一般不推薦 a4.get(0); //返回的,是一個Object對象
理解Java泛型 通配符 ? 以及其使用