Java日誌第32天 2020.8.5
阿新 • • 發佈:2020-08-06
泛型
在前面學習集合時,我們都知道集合中是可以存放任意物件的,只要把物件儲存集合後,那麼這是他們都會被提升成Object型別,當我們在取出每一個物件,並且進行相應操作,這時必須採用型別轉換。
看下面的程式碼:
import java.util.ArrayList; import java.util.Iterator; public class Demo01Generic { public static void main(String[] args) { /* 建立集合物件,不使用泛型 好處:集合不使用泛型,預設的就是Object型別,可以儲存任意型別的資料 弊端:不安全,會發生異常*/ ArrayList list = new ArrayList(); list.add(1); list.add("aaa"); Iterator it = list.iterator(); while(it.hasNext()){ Object obj = it.next(); System.out.println(obj); /* 如果需要使用length()方法來返回字串長度 由於父類不能直接使用子類方法 需要使用向下轉型*/ String s = (String) obj; /* 注意: 編譯器可能會報錯 因為不是所有的資料都是String型別 */ } } }
import java.util.ArrayList; import java.util.Iterator; public class Demo01Generic { public static void main(String[] args) {/* 建立集合物件,使用泛型 好處: 1.避免了型別轉換的麻煩,儲存的是什麼型別,取出的就是什麼型別 2.把執行期異常(程式碼執行之後會丟擲異常),提升到了編譯期(寫程式碼的時候回報錯) 弊端:只能儲存一種型別的資料 */ ArrayList<String> list = new ArrayList(); list.add(1);//報錯 list.add("aaa"); list.add("bbb"); list.add("ccc"); Iterator<String> it = list.iterator(); while(it.hasNext()){ Object obj = it.next(); System.out.println(obj); } } }
泛型的定義與使用
當我們不確定要使用什麼資料型別時,我們可以使用泛型。
泛型可以接受任意資料型別,Integer, String, Student...
public class GenericClass<E> { private E variate; public E getVariate() { return variate; } public void setVariate(E variate) { this.variate = variate; } } public class DemoMain { public static void main(String[] args) { //不使用泛型,預設為Object型別 GenericClass gc = new GenericClass(); gc.setVariate("不使用泛型,預設為Object型別"); Object obj = gc.getVariate(); //建立GenericClass物件,泛型使用Integer型別 GenericClass<Integer> gc2 = new GenericClass<>(); gc2.setVariate(10); Integer integer = gc2.getVariate(); //建立GenericClass物件,泛型使用String型別 GenericClass<String> gc3= new GenericClass<>(); gc3.setVariate("String型別"); String string = gc3.getVariate(); } }
定義和使用含有泛型的方法
格式:
修飾符 < 泛型 > 返回值型別 方法名稱 (引數列表(使用泛型)){
方法體
}
含有泛型的方法,在呼叫方法的時候確定泛型的資料型別
傳遞什麼型別的引數,泛型就是什麼型別
public class Demo02Main { public static void main(String[] args) { GenericMethod gm = new GenericMethod(); gm.method01("abc"); gm.method01(2.5); gm.method01(2); System.out.println("==========="); //呼叫靜態方法 GenericMethod.method02("abc"); GenericMethod.method02(2.5); GenericMethod.method02(2); } }
定義和使用含有泛型的介面
有兩種定義泛型介面的方法:
1.定義介面的實現類,實現介面,指定介面的泛型
2.介面和類使用同一種泛型
public class Demo03Main { public static void main(String[] args) { //建立GenericInterfaceImpl物件 GenericInterfaceImpl gi = new GenericInterfaceImpl(); gi.method("String型別"); //建立GenericInterfaceImpl物件 GenericInterfaceImpl2<String> gi2 = new GenericInterfaceImpl2<>(); gi2.method("abc"); GenericInterfaceImpl2<Integer> gi3 = new GenericInterfaceImpl2<>(); gi3.method(3); GenericInterfaceImpl2<Double> gi4 = new GenericInterfaceImpl2<>(); gi4.method(8.8); } }
泛型萬用字元
當使用泛型類或者介面是,傳遞資料中,泛型型別不確定,可以通過萬用字元<?>表示。但是一旦使用泛型的萬用字元後,只能用Object類中的共性方法,集合中元素自身方法無法使用。
不知道使用什麼型別來接受的時候,此時可以使用?,表示未知萬用字元。
此時只能接受資料,不能往該集合中儲存資料。
使用方式:不能建立物件使用,只能作為方法的引數使用
import java.util.ArrayList; import java.util.Iterator; public class Demo04Generic { public static void main(String[] args) { ArrayList<Integer> arr1 = new ArrayList<>(); arr1.add(1); arr1.add(2); arr1.add(3); ArrayList<String> arr2 = new ArrayList<>(); arr2.add("aaa"); arr2.add("bbb"); arr2.add("ccc"); printArray(arr1); printArray(arr2); } public static void printArray(ArrayList<?> list){ Iterator<?> it = list.iterator(); while(it.hasNext()){ Object obj = it.next(); System.out.println(obj); } } }
泛型的上限限定
? extends E : 代表使用的泛型只能是E型別的子類和本身
泛型的下限限定
? super E : 代表使用的泛型只能是E型別的父類和本身