JAVA 泛型

什么是泛型?

        泛型,很多资料里面解释为“参数化类型”;这种是解释比较抽象,初学者看到这里估计都打退堂鼓了。我们可以将泛型简单理解为一个容器,这个容器可以装水、装酒、装牛奶、装沙子等一切实物(暂时我们先认为可以装一切实物),该容器没有说明书来指定装什么,具体内容完全由使用者决定;但是,容器的使用基本规范是一个容器只允许装一种实物,不能同时装不同的实物;并且容器对里面装的实物的操作不取决于实物本身,比如容器会对里面的实物进行计数、排序、翻转,不会因为里面是液体或者固体而操作不同。

        这样解释是不是容易理解一些。泛型就是这样的,在定义类、接口、方法的时候不指定特定类型,而让类、接口、方法的调用者决定具体使用哪种类型作为参数。在Java中,经常用T、E、K、V等形式的参数来表示泛型参数。

        举个例子:

List arrayList = new ArrayList();
arrayList.add("dog");
arrayList.add(100);

for (int i=0; i<arrayList.size(); i++)  {

    String test = (String)arrayList .get(i));

}

这段代码编译是没有问题的,但是运行时会报错:java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

       泛型可以帮我们在编译阶段有效的检测出上面的类型转换问题。

List<String> arrayList = new ArrayList<String>();
arrayList.add("dog");
arrayList.add(100);

如果我们使用泛型,这段代码在第三行会提示错误:add (java.lang.String) in ArrayList cannot be applied to (int)

   有了泛型以后:

  •    代码更简洁,只需在定义类型时指定参数类型;
  •    代码更健壮,在编译阶段会检查参数是否匹配,避免了运行时做强制类型转换,只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常。

   泛型信息只存在于编译阶段(狗队在编译时不允许站猫),运行阶段就消失了(运行时的队列里没有猫的信息,连狗的信息也没有),这种现象被称为“类型擦除”。

Map<String, Cat> cat = new HashMap<>();
Map<String, Dog> dog = new HashMap<>();
				
System.out.println(cat.getClass());
// 输出:class java.util.HashMap
System.out.println(dog.getClass());
// 输出:class java.util.HashMap

都是输出class java.util.HashMap,也就是说代码在运行时并不知道到map的键上放的是猫还是狗。

试着想想:既然运行时泛型的信息被擦除了,而反射机制是在运行时确定类型信息的,那么利用反射机制,是不是就能够在键位为Cat的Map上放一只Dog呢?

Map<String,String> test = new HashMap<>();
test.put("one","cat");

try {
    Method m = test.getClass().getDeclaredMethod("put", Object.class, Object.class);
    m.invoke(test, "two", 2);
    System.out.println(test);
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

System.out: {one=cat, two=2},竟然在键值都是String的Map里面成功插入int的值。

这是因为,Java的设计者在JDK 1.5时才引入了泛型,但为了照顾以前的设计,同时兼容非泛型的代码,不得不做出了一个折中的策略:编译时对泛型要求严格,运行时却把泛型擦除了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值