【小家java】泛型--那些年我们一起躺过的坑

1、概述

java的泛型是在JDK5开始出现的,在各种设计模式中有非常广泛的应用,比如设计一些基类等,参数化类型(具体的类型参数化)对扩展性能提供很好的支持,避免了不安全的强转安全风险。当然,在java中泛型是“假”的,最终会被擦除,本文就针对于此做一些“坑”的mark

2、栗子说明

下面使用List没有加泛型,存在风险

public static void main(String[] args) {
     List list = new ArrayList();
     list.add("1");
     list.add(2);
     List<String> list2 = list; //不报错 因为类型一样
     list2.forEach(x -> System.out.println(x)); //报错 类型转换异常
}

下面对泛型的使用,一定要当心 小心传错值

public static void main(String[] args) {
     Integer[] ints1 = new Integer[]{1, 2, 3};
     int[] ints2 = new int[]{1, 2, 3};
     doSomething(ints1); //输出1,2,3
     doSomething(ints2); //输出[I@7cca494b 
 }

 private static void doSomething(T... values) {
     for (T value : values) {
         System.out.println(value);
     }
 }

我们发现第二个输出直接把int[]数组的地址打印,因为int[]被作为一个类型值给传递了

public static void main(String[] args) {
    List<String> stringArrayList = new ArrayList<>();
    List<Integer> integerArrayList = new ArrayList<>();
    Class<? extends List> aClass = stringArrayList.getClass();
    Class<? extends List> bClass = integerArrayList.getClass();
    System.out.println(aClass.isAssignableFrom(bClass)); //true
}

输出结果为true,有了上面的基础,这个结果此处就不做过多解释了 对此总结成一句话:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。

  • 泛型的类型参数只能是类类型,不能是简单类型
  • 不能对确切的泛型类型使用instanceof操作

静态方法上引用泛型,需要注意

public static class A<T> {
  public static void get(Class<T> t){ //cannot be referenced from a static method
  }
}

编译报错:静态方法不能在上下文里引用泛型类型

public static class A<T> {
 public void get(Class<T> t){ 
 }
}

这样写就没有毛病了(非静态方法可以直接引用)

public static class A<T> {
   public static <E> void get(Class<E> t) {
   }
}

如果即使是静态方法,但是将泛型定义在方法上就没问题了。注意:必须放在static关键字后面

3、使用场景

综合上面所说,泛型的使用场景可以说是无处不在

4、最后

泛型其实非常好用,保持良好的编码习惯可以减少出错,在实际的编程过程中,自己可以使用泛型去简化开发,且能很好的保证代码质量。更多泛型的基本使用,可参考链接:java泛型使用详解

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券