6.2java泛型的高级应用

(以下不太理解,只是照部分能看懂的搬,不作为参考,只作为笔记)

擦拭法

所谓擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。
例如,我们编写了一个泛型类Pair,但是虚拟机根本不知道泛型,因此造成了两个局限性:

  1. <T>不能是基本类型,例如int,因为虚拟机看到的实际类型应该是Object类,object类无法持有基本类型。(除了八大基本数据类型外,其余的类型都是Object的子类)
  2. 无法取得带泛型的class。当创建实例通过反射获取其class时,获取到的都是泛型的类型,例如:public class Pair<T> {}中获取到的是T类型。
  3. 无法判断带泛型的类型:if (p instanceof Pair<String>) {}原因与上一样。
  4. 不能实例化T类型:
public class Pair<T> {
    private T first;
    private T last;
    public Pair() {
        // Compile error:
        first = new T();
        last = new T();
    }
}

这样的代码编译后会变成这样:

first = new Object();
last = new Object();

创建实例就变成了Object类型
想要成功创建实例,则需要利用反射:

public class Pair<T> {
    private T first;
    private T last;
    public Pair(Class<T> clazz) {
        first = clazz.newInstance();
        last = clazz.newInstance();
    }
}

泛型继承:子类可以继承父类的泛型类

extends通配符

在泛型中,方法传递参数时,若方法传递需要的是一个pair<Number>类型,而我们传递过去的是一个pair<Integer>类型的参数,会出现异常。
因此解决此异常需要用到extends通配符,向上转型
如下demo:

        public static void main(String[] args) {
        Pair<Integer> p = new Pair<>(123, 456);
        int n = add(p);
        System.out.println(n);
    }

    static int add(Pair<? extends Number> p) {
        Number first = p.getFirst();
        Number last = p.getLast();
        return first.intValue() + last.intValue();
    }

可以用extends限定泛型类的类型

public class Pair<T extends Number> { ... }

将T限定在Number中。

super通配符

与extends相反,super通配符是向下转型

    public static void main(String[] args) {
        Pair<Number> p1 = new Pair<>(12.3, 4.56);
        Pair<Integer> p2 = new Pair<>(123, 456);
        setSame(p1, 100);
        setSame(p2, 200);
        System.out.println(p1.getFirst() + ", " + p1.getLast());
        System.out.println(p2.getFirst() + ", " + p2.getLast());
    }

    static void setSame(Pair<? super Integer> p, Integer n) {
        p.setFirst(n);
        p.setLast(n);
    }

使用<? super Integer>通配符作为方法参数,表示方法内部代码对于参数只能写,不能读。
二者对比

  • <? extends T>允许调用读方法T get()获取T的引用,但不允许调用写方法set(T)传入T的引用(传入null除外);
  • <? super T>允许调用写方法set(T)传入T的引用,但不允许调用读方法T get()获取T的引用(获取Object除外)。

PECS原则

PECS原则:Producer Extends Consumer Super。方便记忆何时使用extends或super

无限通配符

无限定通配符<?>很少使用,可以用<T>替换,同时它是所有<T>类型的超类。

泛型和反射

  • 部分反射API是泛型,例如:Class,Constructor;
  • 可以声明带泛型的数组,但不能直接创建带泛型的数组,必须强制转型;
  • 可以通过Array.newInstance(Class, int)创建T[]数组,需要强制转型;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值