泛型程序设计

自己之前对泛型的的设计机制了解的不是太多, 也只是停留在去用的一些表面上。但直到笔者老师上了一课后,猛然感觉这部分内容有点生疏,于是拿起核心技术卷重温了一遍泛型的机制,例如泛型擦除机制 等等。写下此文,记录一些理解

直接进入正题

泛型代码和虚拟机

  • 首先要明白的就只有一件事, java虚拟机没有泛型对象-------所有对象都属于普通类,接下来你就可以编译器是如何擦除类型
泛型擦除机制

直接先看一段代码

public Class Shoe<T>{
	private Double price;
    private T Brand;
    //
    //get and setter and toString
}
  • 解释:上面我们定义一个所谓的泛型类 ,但实际上无论何时定义一个泛型类型,编译器都会自动提供一个与其对应的原始类型 (original type), 这个 original type 就是 类名去掉钻石表达式,也就是上方的 Shoe 类,所以程序中可能有 shoe,shoe,但是一旦编译擦除后,他们都会被擦除成 Shoe .
public Class Shoe{
	private Double price;
    private Object Brand;
    //
    //get and setter and toString
}

// 这就是shoe 类的原始类型
  • 新的问题出现

    如果编译时会将类型擦除,那么下面的这段代码是不是会引发一些思考?

    //main方法内,  Nike 为自定义的一个类
    Shoe<Nike> shoe  = new Shoe<>();
    shoe.add(new Nike());
    shoe.getFirst().showPair();   //showPair() 为Nike的一个方法,查看耐克所有写鞋
    

    既然泛型已经擦除为 Object类,.getFirst() 返回的是Object 类,根据之前老师讲的静态动态绑定 ,Object类不含有showPair()方法,按理会报错。实际却不会,why ?

    转换泛型表达式

    调用 shoe.getFirst() 时,编译器会强制插入字节码指令,将Object 转换 Nike 。

    下面利用反射机制证明泛型擦除

     //在编译时检查泛型,检查完后再将泛型擦除。
            ArrayList<Number> array  = new ArrayList<>();//他要先检查
            array.add(2);
            Integer a = 2;
        //反射方式,获取出集合ArrayList类的class文件对象
            Class c = array.getClass();
            //获取ArrayList.class文件中的方法add
            Method method = c.getMethod("add",Object.class);
            //使用invoke运行ArrayList方法add
            method.invoke(array, 150);
            method.invoke(array, new HashSet<Integer>());
            method.invoke(array, 15000);
            System.out.println(array);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值