java-泛型-为什么不能使用new操作

java-泛型-extends和super

前言

昨天写数据结构-数组的时候想要写这样一段代码:

public class BaseArray<T> {
    private int length;
    private T[] array;
    BaseArray(int length) {
        this.length = length;
        array = new T[length];
    }
}

array = new T[length];这里是不能通过编译的。当时没有细想,所以当时放弃了使用泛型。闲暇之余又想起了这个问题,现在终于弄清楚了这个问题,原来是类型擦除引起的。搜集擦除问题的时候,发现大量泛型-extends和super的问题,这个自己是知道基本概念的,一个是上限通配符,一个是下限通配符,也知道一个不能add,一个不能get,之前自己是有弄清楚这个问题的,现在有所遗忘,所以再一次巩固。

类型擦除

  • Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。如在代码中定义List和List等类型,在编译后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。
  • 泛型不能用于显性地引用运行时类型的操作之中,例如转型,instanceofnew操作(包括new一个对象,new一个数组),因为所有关于参数的类型信息都在运行时丢失了,所以任何在运行时需要获取类型信息的操作都无法进行工作。
    借用网上的一个例子:
public class Abrasion {
    public static void main(String[] args) {
        Class a = new ArrayList<Integer>().getClass();
        Class b = new ArrayList<String>().getClass();
        System.out.println(a == b);
    }
}

以上代码返回:true

extends和super

这个网上有很多的资料,这里就不重复说明,有两句话可以有助于理解:

  • <? extends E> 上限通配符,用来限制类型的上限。List<? extends Fruit> list 你可以理解为这个list可能是List也可能是List或List,只要是Fruit或其子类就行,这时候你要存入一个Orange,也就是add操作的时候,这样是不行的,因为编译器判断不了你这个List是Apple还是Orange还是Banana(因为都可以),所以就只能什么都不能存(null除外),但是使用get获取到的都具有Fruit特性。
  • <? super E> 下限通配符,用来限制类型的下限。List<? super Fruit> list你可以理解为这个list可能是List或List,所以编译器允许你存Fruit或其子类,也就是add操作,而get的类型默认都是Object。

总结

泛型有很多的资料,并且都有不错的代码例子,但是前期可能不好理解,所以需要多多使用,可以先记住简单的结论,以后使用中就可以自然彻底理解。
<? extends E> 适用于使用父类特性,重点在于使用,读取内容。不适合add
<? super E>适用于保存具有父类特性的子类,重点在于保存,写入内容。不适合get

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值