1. 程式人生 > 實用技巧 >Java日誌第32天 2020.8.5

Java日誌第32天 2020.8.5

泛型

在前面學習集合時,我們都知道集合中是可以存放任意物件的,只要把物件儲存集合後,那麼這是他們都會被提升成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型別的父類和本身