JAVA泛型擦除

泛型

泛型,字面意思将一个类泛化,让它适应多种情况(未知情况),使其更具兼容性扩展性。

public class HeapSort<T> {

    T item;
    public HeapSort(){

    }
}

看代码,JAVA中的泛型定义和C++的很是类似,不过相比于C++泛型的强大,JAVA泛型却很是纠结。
因为目前,除了写数据结构之外,JAVA泛型几乎可有可无。这是因为JAVA的一个很重要的特性——擦除。

擦除

擦除,顾名思义泛型类中的某些东西被擦掉了,什么东西呢?就是泛型参数T的具体类型!
是的,JAVA程序运行时,JVM根本不知道你的泛型参数是什么类型,他只知道这是个Object。由于这个特性,在泛型类中做的一些相关于T类内部的所有操作都不会被接受,比如:

T t = new T();
T.a(); //a是T类中的实例方法
//  编译错误

由于擦除,就算你为这个HeapSort《T》创建了实例HeapSort《String》,JVM依然不知道你的T是String,它被想当然的向上转型成Object。这就意味着你的泛型类其实就是复合了Object的普通类。而C++则完全没有这种限制,C++的编译器会在编译期就检查泛型参数T到底是个什么类型,因此有关这个类型内部的所有操作都是正确的。
JAVA这么做是有意义的,在他们看来,因为泛型是1.5之后的性质,为了兼容1.5之前的各种开源库,使得他们不得不这么做(也就是擦除的由来),然并卵,我并不知道这么做的意义有多大=。=
有失去就会有补偿,对于泛型的补偿就是我们可以为泛型参数设置一个擦除的边界。

public class HeapSort<T extends Integer&List> { 
}

这里extends有了新的作用,用于泛型参数的边界设定,意为T是某类和某接口的导出类。这样T就会向上转型成它的基类,因此可以使用基类的方法。
泛型同样可以用于方法,同时JAVA鼓励这样做,可以使用泛型方法完成的任务最好不要使用泛型类。
这里不得不说关于泛型方法的一个小福利——类型推断,在用赋值表达式调用泛型方法时,并不需要指明实参的类型,编译器会帮你判断这应该是个什么类型,比如这样:

public class HeapSort<T> {
    public T a(T bb){
        return null;
    }
    public static void main(String[] args) {
        HeapSort<String> heap = new HeapSort<>();
        String s = heap.a("dfwefg");
    }
}

这使得泛型方法就像普通方法一样,然而其实这并没有什么卵用=。= T的类型已经声明过了,这很好猜。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值