java泛型

什麼時java泛型?java

泛型時jdk1.5版本之後出現的一種對類、方法、接口的一種類型的約束,這種類型的約束是存在與編譯時期的一種約束,在程序的運行時期是沒有泛型的運用。安全

泛型的做用只存在與代碼的編譯時期,運行時沒有泛型的存在ide

泛型即"參數化類型"工具

就是將對象將參數傳遞,爲了可以更好的理解泛型,咱們以上一篇中的分頁工具類來解釋,代碼以下:測試

package com.zs.util;

import com.zs.entity.User;

import java.util.List;

public class PageUtil {
    private int firstPage;
    private int proPage;
    private int currentPage;
    private int nextPage;
    private int lastPage;
    private List<User> list;

    public PageUtil() {

    }
    
    public PageUtil(int currentPage,int countPage, List<User> list) {
        this.firstPage = 1;
        this.currentPage = currentPage;
        this.lastPage = countPage;
        this.proPage = this.currentPage == 1 ? 1 : (this.currentPage - 1);
        this.nextPage = this.currentPage == this.lastPage ? this.currentPage : this.currentPage + 1;
        this.list = list;
    }

    public int getFirstPage() {
        return firstPage;
    }

    public void setFirstPage(int firstPage) {
        this.firstPage = firstPage;
    }

    public int getProPage() {
        return proPage;
    }

    public void setProPage(int proPage) {
        this.proPage = proPage;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getNextPage() {
        return nextPage;
    }

    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }

    public int getLastPage() {
        return lastPage;
    }

    public void setLastPage(int lastPage) {
        this.lastPage = lastPage;
    }

    public List<User> getList() {
        return list;
    }

    public void setList(List<User> list) {
        this.list = list;
    }
}
View Code

這是上一篇中咱們寫的分頁欄的工具,當咱們在前臺點擊了下一頁等跳轉按鈕後,就會發送一個頁數的請求到後臺,後臺將傳遞過來的頁數做爲當前頁,而後獲取當前頁的數據信息,並存入一個集合中,而後經過分頁類的構造方法計算上一頁,下一頁等信息,並將當前頁的信息一併存入工具類裏了。this

上一篇裏例子中,咱們只建立了一個用戶的類,只讀取了user表的數據,那麼若是如今有一個person表,咱們要獲取person表的內容,在一系列操做後獲取了當前頁的內容,咱們要存入List<Person>類型的list中,可是咱們的分頁類PageUtil內的list是一個List<User> 類型的,這樣就出現了類型的不一致,可是分頁的代碼都是同樣的,咱們不能由於這個小緣由,從新建立類,所以咱們就會想,咱們能不能將這個List內的類型看成參數傳遞過去呢,咱們調用方法時,寫的是什麼類型,那麼類內部的List就是什麼類型。spa

這種將對象做爲參數傳遞的行爲就是泛型。3d

仍是前面的pageUtil類,在沒有用泛型時,如今只能傳遞User爲類型的list,那麼咱們將它進行改形成泛型。code

package com.zs.util;

import java.util.List;

public class PageUtil<T> {
    private int firstPage;
    private int proPage;
    private int currentPage;
    private int nextPage;
    private int lastPage;
    private List<T> list;

    public PageUtil() {

    }

    public PageUtil(int currentPage,int countPage, List<T> list) {
        this.firstPage = 1;
        this.currentPage = currentPage;
        this.lastPage = countPage;
        this.proPage = this.currentPage == 1 ? 1 : (this.currentPage - 1);
        this.nextPage = this.currentPage == this.lastPage ? this.currentPage : this.currentPage + 1;
        this.list = list;
    }

    public int getFirstPage() {
        return firstPage;
    }

    public void setFirstPage(int firstPage) {
        this.firstPage = firstPage;
    }

    public int getProPage() {
        return proPage;
    }

    public void setProPage(int proPage) {
        this.proPage = proPage;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getNextPage() {
        return nextPage;
    }

    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }

    public int getLastPage() {
        return lastPage;
    }

    public void setLastPage(int lastPage) {
        this.lastPage = lastPage;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}
View Code

如今這個工具類,就能夠保存各類類型的數據集合了,咱們能夠建立多個類型來測試看能不能放進去。這裏由於還要寫泛型的應用,就不作測試了。對象

泛型的應用:

1.泛型類

package com.zs.service;

/**
 * 泛型的類型相似於object類,什麼類型均可以,可是不能夠使用八大基本類型int、double...,
 * 若是使用八大基本類型的數據,要使用包裝類Integer、Double...
 * 泛型定義在類上public class 類名<泛型類型1,..>能夠定義多個泛型類型
 * @param <E>
 */
public class Demo1<E> {

    private E e;

    public E getE() {
        return e;
    }

    public void setE(E e) {
        this.e = e;
    }
}

這樣就建立了一個簡單的泛型類。e能夠是任意類型,還能夠傳遞多個類型:

package com.zs.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 泛型的類型:T:type  E:element K:key V:value這些都指代類型,沒有區別
 * @param <E>
 * @param <K>
 * @param <Y>
 */
public class Demo2<E,K,Y> {
    private List<E> e;
    private HashMap<K,Y> map;

    public List<E> getE() {
        return e;
    }

    public void setE(List<E> e) {
        this.e = e;
    }

    public HashMap<K, Y> getMap() {
        return map;
    }

    public void setMap(HashMap<K, Y> map) {
        this.map = map;
    }

}

能夠看出,在建立demo的對象是,聲明瞭list的類型爲string類型,所以list只能放string類型,若是存放integer類型會報錯,一樣的demo2裏的hashmap的數據類型爲string,integer

在建立對象時,會根據實力化對象時的類型,自動填充內部的E,K,V等,按照順序填充。

2.泛型方法

package com.zs.service;

public class Demo3 {
    /**
     * 泛型方法的參數類型能夠是任意類型的,可是在聲明方法時,要在返回值前聲明這是個泛型方法<T>
     * @param t
     * @param <T>
     */
    public <T> void fun1(T t) {
        System.out.println("方法執行了" + t);
    }

    public static void main(String[] args) {
        Demo3 demo3 = new Demo3();
        demo3.fun1("字符串");
        demo3.fun1(111);
        demo3.fun1(true);
        /**
         * 運行結果,能夠看到fun內能夠傳任意類型參數
         */
    }
}

3.泛型接口

 

package com.zs.service;

/**
 * 若是一個類實現了泛型接口,那麼這個類必須獲得泛型
 * @param <T>
 */
public class Demo4Impl<T> implements Demo4<T> {
    @Override
    public void fun(T t) {
        System.out.println("執行了" + t);
    }

    public static void main(String[] args) {
        Demo4<String> demo4 = new Demo4Impl<>();
        /*上面聲明瞭泛型類型爲string類型,所以fun只能傳string類型參數*/
        demo4.fun("111");
    }
}

泛型的做用:

  1.提升了程序的安全性(泛型在集合裏的使用)
  2.將運行期遇到的問題,提早到了編譯期

  3.省去了代碼強轉的麻煩

  4.提升了代碼的重用性,實現代碼的公共的封裝

泛型的高級應用:

  1.泛型通配符<?>

  2.<? extends E>

    向下限定,E及其子類

  3.<? supper E>

    向上限定,E及其父類

舉例說明:

package com.zs.service;

import java.util.List;

public class Demo5 {
    /**
     * 通配符類型傳參,至關於object,能夠傳任意類型
     * @param list
     */
    public void fun1(List<?> list) {
        System.out.println(list);
    }

    /**
     * list的類型能夠是demo3或其全部子類類型的
     * @param list
     */
    public void  fun2(List<? extends Demo3> list) {
        System.out.println(list);
    }

    /**
     * list的類型能夠是demo3或其父類類型的
     * @param list
     */
    public void fun3(List<? super Demo3> list) {
        System.out.println(list);
    }
    
}
相關文章
相關標籤/搜索