泛型以及如何绕过泛型定义
泛型定义以及其带来的好处
泛型使类型(类和接口)能够在定义类、接口和方法时成为参数。与方法声明中使用的更熟悉的形式参数非常相似,类型参数为您提供了一种通过不同输入重复使用相同代码的方法。区别在于形式参数的输入是值,而类型参数的输入是类型。
使用泛型的代码比非泛型代码有很多好处:
- 编译时更强的类型检查。 Java 编译器对泛型代码应用强类型检查,如果代码违反类型安全,则会发出错误。修复编译时错误比修复运行时错误更容易,后者很难发现。
- 避免类型转换
以下没有泛型的代码片段需要强制转换:
1 | List list = new ArrayList(); |
当重写为使用泛型时,代码不需要转换:
1 | List<String> list = new ArrayList<String>(); |
- 使程序员能够实现通用算法。 通过使用泛型,程序员可以实现适用于不同类型集合的泛型算法,可以自定义,并且类型安全且更易于阅读。
绕过泛型定义
使用反射
1 | public static void main(String[] args) throws Exception { |
输出结果:
1 | [aa, bb, 123] |
注意:
如果通过循环遍历输出list的元素,比如
1 | for(String str : list) { |
或者
1 | list.stream().forEach(p -> System.out.println(p)); |
就会报错:
1 | aa |
这是因为遍历的时候,会把集合里的元素拿出来,作为泛型定义的String类型输出,而我们通过反射添加了一个Integer类型的值,因此造成类型转换错误。
除非我们这样遍历输出:
1 | for(Object str : list) { |
输出结果:
1 | aa |