1. 程式人生 > >泛型1:介紹及基本使用方式

泛型1:介紹及基本使用方式

前言 編譯 color eno 核心 AC fix tor 生成器

前言

  • 泛型實現了參數化類型的概念;
  • 泛型的主要目的之一是用來指定容器要持有什麽類型的對象,編譯器保證類型的正確性;
  • 多態也是一種泛化機制;
  • 基本類型無法作為類型參數;

    一.基本使用方式

      泛型基本分為泛型類型和泛型方法兩種,泛型類型聲明方式為類型參數用尖括號括住,放在類名後邊,泛型方法的參數列表應該置於返回值之前。示例如下:

//泛型類
package java.lang;

public interface Iterable<T> {
    Iterator<T> iterator();

    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    default Spliterator<T> spliterator() {
         return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

//泛型方法
public class GenericMethods{
    public <T> void f(T t){
        System.out.println(t.getClass().getName());
    }
}
  • 應該優先使用泛型方法,而非將泛型應用到整個類上;
  • 泛型的核心概念是告訴編譯器想使用什麽類型,然後讓編譯器處理細節.

二.使用場景

1.元組類庫

  即當調用一個方法希望返回多個對象時,需要將一組對象直接打包存儲在一個對象中——這也是元祖的概念。元組中的對象可以是不同的類型。示例代碼如下:

//二維元祖
public class TwoTuple<A,B>{
    public final A first;//fixme 註意是final類型的
    public final B second;

    public TwoTuple(A first, B second) {
        this.first = first;
        this.second = second;
    }
}

//使用繼承機制實現的三維元祖
class ThreeTuple<A,B,C> extends TwoTuple<A,B>{
    public final C third;

    public ThreeTuple(A first, B second, C third) {
        super(first, second);
        this.third = third;
    }
}
  • 使用繼承機制實現更長的元組;
  • 變量為final類型保證了元組對象被創建後,final元素便不能被改變了;

    2.實現堆棧類

      可以使用泛型類實現自定義的鏈表棧,示例如下:
    ```
    package fanxing;

public class LinkedStack

    public Node(U item, Node<U> next) {
        this.item = item;
        this.next = next;
    }
    //末端哨兵(end sentinel)
    boolean end(){
        return item==null&&next==null;
    }
}
private Node<T> top=new Node<>();
//每push一次都會創建一個對象並放到棧尾
public void push(T item){
    top=new Node<>(item,top);
}

public T pop(){
    T result=top.item;
    if(!top.end()){
        top=top.next;
    }
    return result;
}

public static void main(String[] args) {
    LinkedStack<String> lss=new LinkedStack<>();
    for(String str:"du gen kui".split(" "))
        lss.push(str);
    String s;
    while((s=lss.pop())!=null)
        System.out.println(s);
}

}
```

3.用於工廠方法設計模式

  泛型可以用於接口,比如生成器(generator),工廠方法設計模式是其一中應用。例如crawl4j中的工廠方法:

public interface WebCrawlerFactory<T extends WebCrawler> {
    T newInstance() throws Exception;
}

//補充:默認工廠的實現
class DefaultWebCrawlerFactory<T extends WebCrawler> implements WebCrawlerFactory<T>{
    final Class<T> claz;
    DefaultWebCrawlerFactory(Class<T> clz){ this.clz=clz;}
    
    @Override
    public T newInstance() throw Exception{
        try{
            return clz.newInstance();
        }catch(ReflectiveOperationException e){
            throw e;
        }
    }
}
4.補充:可變參數列表

  將方法參數項寫成T... x的形式就可以將其作為可變參數列表。示例如下:

public class VariableParam<T> {

    public void testFunc(T... params){
        for (T ele:params) {
            System.out.println(ele.toString());
        }
    }

    public static void main(String[] args) {
        new VariableParam<String>().testFunc("du","gen","kui");
    }
}

泛型1:介紹及基本使用方式