JDK1.5后增加了泛型,那么为什么要有泛型呢?我们该如何自定义

2022-11-05  本文已影响0人  分布式与微服务

本篇主要讲解java泛型的理解、集合中简单使用泛型、自定义泛型结构(包括类、接口、方法)。


一、什么是泛型?

通俗来讲,可以把泛型理解为带有标签的罐子,罐子贴着红糖的标签,就只能放红糖;罐子贴着白糖的标签,就只能放白糖,不可以乱放。用集合来解释,可以理解为:

list贴上了String的泛型标签,就只能添加String类型的数据;list1贴上了Integer的泛型标签,就只能添加Integer类型的数据;否则就会报错。


二、泛型的概念

public interface List<E> extends Collection<E> {
    Iterator<E> iterator();
    <T> T[] toArray(T[] a);
    boolean add(E e);


三、为什么要设计泛型?

所以为什么要有泛型呢?直接用Object类型存储数据不香吗?

以集合为例,当我们不使用泛型时:

    public void test1() {
        List<Object> list = new ArrayList<>();
        list.add(123);
        list.add(456);
        list.add("789");
        for (Object o : list) {
            Integer item = (Integer) o;
            System.out.println(item);
        }
    }

运行结果:

当我们使用泛型时:

    public void test2() {
        List<Integer> list = new ArrayList<>();
        list.add(123);
        list.add(456);
//        list.add("789");添加失败
        for (Integer integer : list) {
            System.out.println(integer);
        }
    }
我们可以发现,使用泛型后,当添加的数据类型不满足条件时,编译就会报错;在遍历集合时,还可以避免强制类型转换。

四、自定义泛型结构

1、自定义泛型类

public class Order<T> {
    String orderName;
    int orderId;
    //类的内部结构就可以使用类的泛型
    T orderT;
    //构造器
    public Order(){
        //泛型数组
        T[] arr = (T[]) new Object[8];
    }
    public Order(String orderName,int orderId,T orderT){
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderT = orderT;
    }
    //注意,下面的三个方法都不是泛型方法
    public T getOrderT(){
        return orderT;
    }
    public void setOrderT(T orderT){
        this.orderT = orderT;
    }
    @Override
    public String toString() {
        return "Order{" +
                "orderName='" + orderName + '\'' +
                ", orderId=" + orderId +
                ", orderT=" + orderT +
                '}';
    }
}

需要注意的是:


2、自定义泛型接口

由于类和接口没有很大的区别,所以为了文章的完整性,就继续以类来讲解泛型相关的知识:

class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father {// 等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2 extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2> extends Father<Integer, T2> {
}

class Father<T1, T2> {
}
// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son<A, B> extends Father{//等价于class Son extends Father<Object,Object>{
}
// 2)具体类型
class Son2<A, B> extends Father<Integer, String> {
}
// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2, A, B> extends Father<T1, T2> {
}
// 2)部分保留
class Son4<T2, A, B> extends Father<Integer, T2> {
}

总结:


3、自定义泛型方法

    //这些都是泛型方法:
    public <E> void say(List<E> list) { }

    public static <E> List<E> copyFromArrayToList(E[] arr) {
       ArrayList<E> list = new ArrayList<>();
       for (E e : arr)
           list.add(e);
       return list;
    }
上一篇下一篇

猜你喜欢

热点阅读