天天看點

Java之泛型基礎java之泛型基礎

java之泛型基礎

一:簡介

從這裡開始再次回顧一下java基礎,目的是再次深入一點學習,不是教程,主要以相關知識的重點為主,有時候可能有較強的偏向性,是以可能會遺漏一些基礎概念或者之類的東西。泛型學習筆記上篇,主要記錄java泛型相關基礎,包括為什麼引入泛型,泛型的使用方式,以及在JDK或架構中的典型應用。

二:泛型的概念

泛型是Java SE 1.5的新特性,泛型的本質是參數化類型,也就是說所操作的資料類型被指定為一個參數。這種參數類型可以用在類、接口和方法的建立中,分别稱為泛型類、泛型接口、泛型方法。

三:為什麼要使用泛型

  • 類型安全—— 泛型的主要目标是提高 Java 程式的類型安全。使得java代碼可以編譯時期檢查出因java類型導緻的可能在運作時抛出ClassCastException異常。符合越早出錯代價越小原則。
  • 消除強制類型轉換—— 泛型的一個附帶好處是,消除源代碼中的許多強制類型轉換。這使得代碼更加可讀,并且減少了出錯機會。
  • 潛在的性能收益—— 泛型為較大的優化帶來可能。在泛型的初始實作中,編譯器将強制類型轉換(沒有泛型的話,程式員會指定這些強制類型轉換)插入生成的位元組碼中。但是更多類型資訊可用于編譯器這一事實,為未來版本的 JVM 的優化帶來可能。由于泛型的實作方式,支援泛型(幾乎)不需要 JVM 或類檔案更改。所有工作都在編譯器中完成,編譯器生成類似于沒有泛型(和強制類型轉換)時所寫的代碼,隻是更能確定類型安全而已。

四:泛型文法

如在概念中提到,參數化類型可以用在類、接口、方法上。

泛型類:

public class GenericClass<T>{
    private T t;

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }
}
           

泛型接口

public interface GenericInterface<T> {
    void method(T t);
}
           

泛型方法

public <E> E genericMethod(E e){
        return e;
    }
           

五:典型應用

關于泛型,我們最常見的就是在JDK的集合中見到,并且使用。簡單的看一個典型的集合類:Collection。
           
public interface Collection<E> extends Iterable<E> {
    // Query Operations

    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();

    Object[] toArray();

    <T> T[] toArray(T[] a);

    // Modification Operations

    boolean add(E e);

    boolean remove(Object o);


    // Bulk Operations

    boolean containsAll(Collection<?> c);

    boolean addAll(Collection<? extends E> c);

    boolean removeAll(Collection<?> c);

    default boolean removeIf(Predicate<? super E> filter) {
        Objects.requireNonNull(filter);
        boolean removed = false;
        final Iterator<E> each = iterator();
        while (each.hasNext()) {
            if (filter.test(each.next())) {
                each.remove();
                removed = true;
            }
        }
        return removed;
    }

    boolean retainAll(Collection<?> c);

    void clear();


    // Comparison and hashing

    boolean equals(Object o);

    int hashCode();

    /**
     * default 關鍵字是java1.8引入的一個新特性,有興趣的可以自行了解一下
     * 相關的Spliterator和Stream以及前面的Predicate都是1.8新引入的接口
     */

    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, );
    }

    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }

    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}
           

從Spring的BeanFactory中擷取Bean的方法

<T> T getBean(String name, Class<T> requiredType) throws BeansException;
           

泛型使用規則

  1. 泛型的類型參數隻能是類類型(包括自定義類),不能是簡單類型。
  2. 同一種泛型可以對應多個版本(因為參數類型是不确定的),不同版本的泛型類執行個體是不相容的。
  3. 泛型的類型參數可以有多個。
  4. 泛型的參數類型可以使用extends語句,例如。習慣上稱為“有界類型”。
  5. 泛型的參數類型還可以是通配符類型。例如Class

總結:

這裡隻記錄了泛型最基本的一些知識,連泛型的邊界都沒有涉及到,目的是想讓結構清晰一點。接下來的泛型進階,和泛型最佳實戰會深入了解。