Java 泛型擦除小实验
磊磊

简介

  • 很多人看到泛型就害怕,其实你只要想象成人为的一个约束。
  • 泛型是编译期间的行为,下面会通过程序运行时的反射案例校验。
  • 泛型是防止错误输入的,本质上就是 Object,存在的意义是方便编码确认类型。只在编译阶段有效 – 绕过编译无效

案例

Test.Java 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
@org.junit.Test
public void test1() throws Exception {
List<String> list = new ArrayList<>();
list.add("A");
// 编译报错,类型不同不能转换
// list.add(1);
@SuppressWarnings("rawtypes")
Class<? extends List> aClass = list.getClass();
aClass.getMethod("add", Object.class).invoke(list, 666);
System.out.println(list);
System.out.println((String) list.get(0));
System.out.println((String) list.get(1));
}

image

过程

  • 通过反射(运行时执行方法),把 Integer 类型 666 放入 list 中。

  • 可知道程序运行时 List<String> 并没有被约束(即放入时就报错)。

  • 所以 List<String> 就相当于 List<Object> 所以可以取出来。

  • 由于是泛型返回值类型自动强转(可以看 class 文件结果),强转会会报运行时异常。

结论

  • 所以 Java 的泛型只是编译期的约束行为。 应该尽量避免这种运行时能赋值非泛型类型值的行为,不然会导致后面自动强转报运行错误。
由 Hexo 驱动 & 主题 Keep
访客数 访问量