Java泛型与类型擦除

为什么出现泛型

早期Java没有泛型,每次从List中取数据要强转,使用泛型后在定义List时就定义好一个类型,每次取数据不用强转了

类型擦除

java的泛型使用类型擦除来实现,在编译时删掉泛型声明,使所有T声明等价于Object,加入强转,运行时无发获取泛型的类型
测试类:

public class c01<T extends Reader> {

    void bar(String s){}

    void foo(){
        List list1 = new ArrayList<String>();
        List<String> list2 = new ArrayList<>();
        c01 obj1 = new c01<BufferedReader>();
//      c01 obj2 = new c01<String>(); 编译报错
        list2.add("1");
        bar(list2.get(0));
    }
}

反编译后

public class c01<T extends Reader> {          //Line Num
    public c01() {                            // 1
    }                                         // 2
                                              // 3
    void bar(String var1) {                   // 4
    }                                         // 5
                                              // 6
    void foo() {                              // 7
        new ArrayList();                      // 8
        ArrayList var2 = new ArrayList();     // 9
        new c01();                            // 10
        var2.add("1");                        // 11
        this.bar((String)var2.get(0));        // 12
    }
}

从上面的代码可以看到:
1: c01 obj1 = new c01<BufferedReader>();在反编译后变成了new c01();
2: list2.get(0)在反编译后变成了(String)var2.get(0)被编译器自动加上了强转
3: List list1 = new ArrayList<String>();在反编译后变成了new ArrayList();说明泛型完全没起到作用,即使在java代码中向list1中插入其他类型也只会得到一条警告,不影响运行。

如何在普通类声明泛型

void funlist(List<? super Reader> list){
    }

<R extends Reader> void funlist2(List<R> list){
}

?通配符的意义

示例代码

public class c03 {

    class A{}

    class B extends A{}

    void foo(){
        A[] x = null;
        B[] y = new B[]{new B()};
        List<A> aa = null;
        List<B> bb = null;
        test(y);                            //正常运行
//        t2(bb);                           //编译器提示报错,类型不匹配
        boolean ret = y instanceof A[];     //编译器提示,always true
    }

    void test(A[] aaa){}

    void t2(List<A> parm){}
}

也就是说如果B继承A,那么B数组继承与A数组,但B集合不继承于A集合
当我们真的想表示一个类型子类的集合的时候就需要使用通配符?来实现。

通配符集合只能get,不能put,即使在指定了上下边界的情况下。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值