Java泛型的作用以及如何使用(继承、接口、方法、通配符) 附源码

🍋1. 泛型的定义

class 类名称<泛型标识, 泛型标识, ....>{
    private 泛型标识 变量名称;
    .......
}

常用的泛型标识字符 :T, E, K, V

  • E - Element (在集合中使用,由于集合中存放的是元素),E是对各方法中的泛型类型进行限制,以保证同一个对象调用不一样的方法时,操做的类型一定是相同的。E能够用其它任意字母代替
  •  T - Type(Java 类),T表明在调用时的指定类型。会进行类型推断
  •  K - Key(键)
  •  V - Value(值)
  •  N - Number(数值类型)

我们以下面代码为例定义一个泛型类

public class Test<T> {
    private T key;

    public Test(T key) {
        this.key = key;
    }

    public T getKey() {
        return key;
    }

    public void setKey(T key) {
        this.key = key;
    }

    @Override
    public String toString() {
        return "Generic{" +
                "key=" + key +
                '}';
    }
}

创建一个泛型类对象, 并指定为String类型

    public static void main(String[] args) {
        //这里我们指定的String类型
        Generic<String> str = new Generic<>("aaa");
        //返回的类型也是String
        String key = str.getKey();

        //这里我们指定的Integer类型
        Generic<Integer> integer = new Generic<>(1);
        //返回的类型也是Integer
        Integer key1 = integer.getKey();
    }

 🍓2. 泛型的两种继承

方式1 :  泛型派生子类, 子类也是泛型, 那么子类的泛型标识要个父类的保持一致

public class Child<T> extends Parent<T> {

}

方式2 : 泛型派生子类, 如果子类不是泛型类, 那么父类要明确数据类型

public class ChildTow extends Parent<Integer> {
}

🍔3. 泛型接口 

/**
 * 泛型接口
 * @param <T>
 */
public interface Generator<T> {
    T getKey();
}

方式1 : 实现泛型接口的类不是泛型, 需要明确实现泛型接口的数据类型

public class Apple implements Generator<String>{
    @Override
    public String getKey() {
        return "hello";
    }
}

方式2 : 泛型接口的实现类, 是一个泛型类, 那么要保证实现接口的泛型类标识 和泛型接口的一致

public class Pair<T, E> implements Generator<T> {

    @Override
    public T getKey() {
        return null;
    }

}

🍭4. 泛型方法

泛型方法的定义

    /**
     * 测试自定义泛型方法
     * @param list 参数
     * @param <E> 泛型标识, 具体类型, 由调用方法的时候来指定
     * @return
     */
    public <E> E getOne(ArrayList<E> list){
        //返回第一个元素
        return list.get(0);
    }

泛型方法的调用 : 泛型方法的调用, 类型是通过调用方法的时候来指定的

    public static void main(String[] args) {
        Test test = new Test();
        ArrayList<String> str = new ArrayList<>();
        str.add("测试001");
        String one = test.getOne(str);
        System.out.println("one = " + one);

        ArrayList<Integer> num = new ArrayList<>();
        num.add(996);
        System.out.println("num = " + num);
    }

静态泛型方法的定义(多个参数)  泛型可变参数的定义

    /**
     * 泛型可变参数的定义
     * @param e
     * @param <E>
     */
    public static <E> void print(E... e){
        for (E value : e) {
            System.out.println("参数 : " + value);
        }
    }

    //调用
    Test.print("测试", 111, 2.2, new ArrayList<>());


🥭5. 泛型类型通配符

1. 类型通配符上线 :

要求该泛型的类型, 只能是实参类型, 或者实参类型类的类型

下面以Integer为例, 它的父类就是Number类型, 这一点我们从源码中就能得知

        

 实现代码如下,

    public static void showBox(Box<? extends Number> box){
        Number first = box.getFirst();
        System.out.println("first = " + first);
    }

我们最后传入的参数只能是Number以及他的子类Integer类型

    public static void main(String[] args) {
        Box<Integer> objectBox = new Box<>();
        objectBox.setFirst(11111);
        showBox(objectBox);
    }

2.类型通配符下线 : 

要求该泛型的类型, 只能是实参类型, 或者实参类型类的类型

这里为了便于讲解实现了三个类

/**
 * 爷爷类
 */
public class Grandfather {
}
/**
 * 父亲类
 */
public class Father extends Grandfather{
}
/**
 * 儿子类
 */
public class Son extends Father {
}

下线通配符代码实现如下

    public static void family(List<? super Father> item){
        for (Object o : item) {
            System.out.println(o);
        }
    }

    //调用
    family(new ArrayList<Son>());
    family(new ArrayList<Grandfather>());

可以看出当下线设置为<? super Father> 的时候传入的参数只能是爸爸的上级也就是爷爷类(Grandfather), 传入儿子类(Son)就会产生报错


🍖6. 泛型代码

扫描下方公众号二维码 回复: 泛型 即可领取项目源码 👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Max恒

为了开源加油 ! !

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值