Object与泛型

13 阅读2分钟

先介绍一下泛型: java 中泛型标记符:

  • E - Element (在集合中使用,因为集合中存放的是元素)
  • T - Type(Java 类)
  • K - Key(键)
  • V - Value(值)
  • N - Number(数值类型)
  •  - 表示不确定的 java 类型

声明泛型类不能用无界通配符<?>

//编译报错
class Box<?>{
    private ? item1;
    private ? item2;
}

泛型擦除概念

Java的泛型是伪泛型,这是因为Java在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。Java的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程成为类型擦除。
例如:List<String> 和 List<Integer> 在编译后都变成 List

详见: Java 泛型擦除 - hongdada - 博客园 (cnblogs.com)

由此:当使用泛型时,泛型已经确定类型

先看如下代码:

public class tmain<T> {
    public static void main(String[] args) {
        tmain tmain = new tmain<RechargeRecord>();

        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setOutTradeNo("123456");

        tmain.processPay(new PayService<RechargeRecord>() {
            @Override
            public void paySuccess(String outTradeNo, RechargeRecord rechargeRecord) {
                System.out.println("-----> success"+rechargeRecord.getOutTradeNo());
            }

            @Override
            public void payFail(String outTradeNo) {
                System.out.println("-----> fail"+outTradeNo);
            }
        }, rechargeRecord);
    }
    void processPay(PayService payService, T t){
        payService.paySuccess("123", t);
    }
}
// 泛型接口
interface PayService<T>{
    void paySuccess(String outTradeNo, T t);
    void payFail(String outTradeNo);
}

结果:-----> success123456

如果使用Object来写如下:

public class tmain {
    public static void main(String[] args) {
        RechargeRecord rechargeRecord = new RechargeRecord();
        rechargeRecord.setOutTradeNo("123456");

        new tmain().payProcess(new PayService() {
            @Override
            public void paySuccess(String outTradeNo, Object object) {
                RechargeRecord rechargeRecord1 = (RechargeRecord) object;
                System.out.println("-----> success"+rechargeRecord1.getOutTradeNo());
            }

            @Override
            public void payFail(String outTradeNo) {

            }
        }, rechargeRecord);
    }
    void payProcess(PayService payService, Object object){
        payService.paySuccess("12342345", object);
    }
}

结果:-----> success123456

使用泛型,有2个好处:

1.不需要做强制类型转换

2.编译时更安全。如果使用Object类的话,你没法保证返回的类型一定是Foo,也许是其它类型。这时你就会在运行时得到一个类型转换异常(ClassCastException)