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

Posted coderDu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型1:介绍及基本使用方式相关的知识,希望对你有一定的参考价值。

前言

  • 泛型实现了参数化类型的概念;
  • 泛型的主要目的之一是用来指定容器要持有什么类型的对象,编译器保证类型的正确性;
  • 多态也是一种泛化机制;
  • 基本类型无法作为类型参数;

    一.基本使用方式

      泛型基本分为泛型类型和泛型方法两种,泛型类型声明方式为类型参数用尖括号括住,放在类名后边,泛型方法的参数列表应该置于返回值之前。示例如下:

//泛型类
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:介绍及基本使用方式的主要内容,如果未能解决你的问题,请参考以下文章

WeihanLi.Redis自定义序列化及压缩方式

Github介绍与使用

Github介绍与使用

什么是泛型?泛型的基本原理与使用优势。

c++师傅领进门,修行靠个人第七篇:C++模板

c++师傅领进门,修行靠个人第七篇:C++模板