集合(8):泛型類、泛型方法、泛型接口


集合(8):泛型類、泛型方法、泛型接口

前言案例

import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo1 {
    public static void main(String[] args) {
        //創建List集合對象
        ArrayList list = new ArrayList();
        //向集合中添加元素
        list.add("hello");
        list.add(10);//相當於向上轉型,10 -- int -- Integer
        list.add("world");
        //獲取迭代器對象
        Iterator iterator = list.iterator();
        //獲取迭代器對象
        while(iterator.hasNext()){
            Object next = iterator.next();
            String s = (String)next;
            System.out.println(s);
        }
    }
}

執行結果如下:

image

我們按照正常的寫法,在集合中添加一些不是同類型的數據,在遍歷的時候向下轉型報錯了
ClassCastException:類型轉換異常
為什么呢?
    因為我們在存儲數據的時候,存儲了一些String和Integer類型的數據,但是呢,
    我們遍歷的時候,默認集合中只存放String類型的數據;但是在存儲數據的時候
    沒有告訴我們只能存String類型的數據,如果能在存儲的時候告訴我能存儲哪些數據類型就好了
    String[] arr = new String[3];//創建數組的時候明確的元素的類型
          arr[0] = "hello";
       // arr[1] = 20;當添加int類型的時候是不可行的

java中集合就模仿着數組呢,也有這樣的做法,在創建集合的時候,就明確了元素的數據類型,
創建后,再往集合中加入的元素,只能是定義好的數據類型相關的數據了,然后再向下轉型就沒有問題了。
這樣的技術,java中叫做:泛型

泛型

一、泛型的使用介紹

1、泛型的概述
把明確數據類型的工作,提前到了編譯時期,在創建集合的時候明確數據類型,
這樣的做法有點像把數據類型當作參數一樣進行傳遞。
所以泛型還有一個名字叫做:參數化類型
2、泛型的定義格式
定義格式:
     <引用數據類型>,在API中是<E>
     注意:尖括號中的數據類型只能是引用數據類型,<E>在創建對象的時候添加在類后面

格式案例:

ArrayList<String> list = new ArrayList<String>();

JDK1.7之后會自動進行類型推斷
所以后面的<String>中的String可加可不加,建議加上
當創建對象的時候加入了泛型,迭代器也要加上泛型
//獲取迭代器對象
Iterator<String> iterator = list.iterator();
在沒使用泛型的時候,添加不同類型元素的時候,不會報錯,在向下轉型的時候才會報錯;
當使用泛型的時候,在添加元素的時候,編寫代碼的時候就會報錯,提前報錯,便於我們更改
3、泛型的好處
添加泛型之后
(1)將我們之前運行時候出現的問題,提前到了編譯時期
(2)不需要強制類型轉換了,而且還可以調用元素類型的方法
(3)優化了代碼,消除不必要的黃色警告線
4、泛型的使用場景
通過觀察API發現,泛型可以出現了類,接口,方法上,看到一些類似與<E>,
一般來說泛型出現在大多使用集合中

二、泛型的應用

1、泛型類
泛型類:把泛型定義在類上(在類名后面添加<變量名>)
格式:public class 類名<泛型類型1,…>
注意:泛型類型必須是引用類型
這里的<>里面的內容僅僅表示的是一種參數數據類型,參數類型是一種變量,
既然是一種變量,就符合變量的命名規則,可以是任意符合標識符起名規則的名字

泛型類的使用

//第1步:定義一個泛型類
class GenericTool1<T> {
    private T obj;

    public T getObj() {
        return obj;
    }

    public void setObj(T obj) {
        this.obj = obj;
    }
}

//第2步:泛型類的測試
public class GenericTest1 {
    public static void main(String[] args) {
    /*
    	如果前面定義的類不加泛型,默認則是Object類型
		GenericTool1 gt1 = new GenericTool1();
		添加元素的時候,類型可以是任意的
		gt1.setObj("hello");
		gt1.setObj(20);
		gt1.setObj(12.34);
		gt1.setObj(new Student());
    */
		//創建泛型類的對象
        GenericTool1<String> gt = new GenericTool1<>();
        //調用setObj()方法添加元素
        gt.setObj("hello");
		//gt2.setObj(20);定義過泛型之后,就不能再添加不同類型的元素
		
        //調用getObj()方法獲取元素
        String obj = gt.getObj();
        System.out.println(obj);
    }
}
            執行結果如下:
                        hello

                        Process finished with exit code 0
2、泛型方法
泛型方法:把泛型定義在方法上

格式:public <泛型類型> 返回類型 方法名(泛型類型 .)
    例:
	public<T> void show(T t){}

(1)在沒使用泛型的時候,正常寫個類來定義成員方法

//定義一個類
public class GenericTool2 {
    public void show(String s){
        System.out.println(s);
    }

    public void show(int i){
        System.out.println(i);
    }
    
     public void show(double d){
        System.out.println(d);
     }
}

//定義一個測試類
public class GenericTest2 {
    public static void main(String[] args) {
    //創建類的對象
	GenericTool2 gt1 = new GenericTool2();
    //調取類中的show方法,並賦值
	gt1.show(10);
	gt1.show("hello");
	gt1.show(12.34);
 	}
}
            執行結果如下:
                        10
                        hello
                        12.34

                        Process finished with exit code 0

當我們不使用泛型的時候,在測試類中賦值的時候,必須要根據定義的成員方法參數類型來賦值,

當需要賦值很多類型的時候,需要定義的成員方法也很多,非常的麻煩。

(2)當使用泛型類的時候,泛型類的成員方法參數類型和泛型類一致

賦值很多類型的時候,就不需要定義很多發成員方法了

//定義一個泛型類
class GenericTool2<T> {
    //定義成員方法,參數為T類型
    public void show(T t){
        System.out.println(t);
    }
}
//定義一個測試類
public class GenericTest2 {
    public static void main(String[] args) {
        GenericTool2 gt1 = new GenericTool2();
        //前面定義了泛型類,此處再賦值就可以隨便賦值不同的類型了
        gt1.show(10);
        gt1.show("hello");
        gt1.show(12.34);
    }
}
     		執行結果如下:
                        10
                        hello
                        12.34

                        Process finished with exit code 0

(3)當定義了泛型類,泛型類的成員方法參數類型和泛型類一致,

如果在測試了中創建對象的時候也加上了泛型,會發生什么變化?

//定義一個泛型類
class GenericTool2<T> {
    //定義泛型成員方法
    public void show(T t){
        System.out.println(t);
    }
}
//定義一個測試類
public class GenericTest2 {
    public static void main(String[] args) {
        //創建泛型類對象的時候加上泛型
        GenericTool2<String> gt2 = new GenericTool2<>();
        gt2.show("hello");
        //gt2.show(20);當創建對象的時候加上了泛型,那么賦值int類型就會報錯
        //想要賦值int類型的元素,就必須再創建一個int泛型的對象
        GenericTool2<Integer> gt3 = new GenericTool2<>();
        gt3.show(20);
    }
}
        執行結果如下:
                    hello
                    20

                    Process finished with exit code 0

由此可見,當定義了泛型類,泛型類的成員方法參數類型和泛型類一致,

在測試了中創建對象的時候也加上了泛型,

賦值不同類型的時候,需要創建很多的對象,就非常的麻煩

如果定義的類上面沒有泛型的話,方法還能不能隨便傳參呢?

答案是可以的,不過這時候就需要用到泛型方法

而且測試類中創建對象的時候不能有泛型了,不然會報錯

//定義一個類
public class GenericTool2 {
    //定義泛型成員方法
    public<T> void show(T t){
        System.out.println(t);
    }
}
//定義一個測試類
public class GenericTest2 {
    public static void main(String[] args) {
        //創建對象
        GenericTool2 gt = new GenericTool2();
        //定義泛型方法以后,賦值的時候,可以傳入任意類型的參數
        gt.show("hello");
        gt.show(20);
        gt.show(true);
    }
}
        執行結果如下:
                    hello
                    20
                    true

                    Process finished with exit code 0
3、泛型接口
泛型接口:把泛型定義在接口上
格式:public interface 接口名<泛型類型1...>

案例:

//定義泛型接口,接口中的方法參數和接口一致
public interface GenericTool3<T> {
    public abstract void show(T t);
}
//定義一個類來實現泛型接口,實現接口的類也要加上泛型
public class GenericTool3Impl<T> implements GenericTool3<T>{
    //重寫接口中的抽象方法
    @Override
    public void show(T t) {
        System.out.println(t);
    }
}
//泛型接口的測試
public class GenericTest3 {
    public static void main(String[] args) {
        //接口不能實例化,需要new它的實現類
        GenericTool3Impl<String> sgt1 = new GenericTool3Impl<>();
        sgt1.show("hello");
    }
}

執行結果如下:

hello

Process finished with exit code 0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM