目录
在泛型为 Integer 的 ArrayList 中存放一个 String 类型的对象
面试回答
Java 泛型(generics)是 JDK 5 引入的一个新特性,允许在定义类和接口的时候使用类型参数(type parameter)。声明的类型参数在使用时用具体的类型来替换。泛型最主要的应用时在 JDK 5 中的新集合类框架中。
泛型的好处有两个:
- 方便:可以提高代码的复用性。以 List 接口为例,我们可以将 String、Integer 等类型放入 List 中,如不用泛型,存放 String 类型要写一个 List 接口,存放 Integer 要写另外一个 List 接口,泛型可以很好的解决这个问题。
- 安全:在泛型出之前,通过 Object 实现的类型转换需要在运行时检查,如果类型转换出错,程序直接 GG,可能会带来毁灭性打击。而泛型的作用就是在编译时做类型检查,我无疑增加程序的安全性。
知识扩展
泛型时如何实现的
Java 中的泛型通过类型擦除的方式来实现,通俗点理解,就是通过语法糖的形式,在 .java
-> .class
转换的阶段,将 List<String> 擦除调转为 List 的手段。换句话说,Java 的泛型只在编译期,JVM 是不会感知到泛型的。
类型擦除的缺点有哪些?
- 泛型不可以重载
- 泛型异常类不可以多次 catch
- 泛型类中的静态变量也只有一份,不会有多份
List<?>,List<Object>,List 之间的区别
List<?>
是一个未知类型的List
,而List<Object>
其实是任意类型的List
。可以把List<String>
,List<Integer>
赋值给List<?>
,去不能把List<String>
赋值给List<Object>
- 可以把任何带参数的类型传递给原始类型
List
,但却不能把List<String>
赋值给List<Object>
,因为会产生编译错误(不支持协变)。
在泛型为 Integer 的 ArrayList 中存放一个 String 类型的对象
通过反射可以实现:
public static void main(String[] args) throws Exception {
ArrayList<Integer> list=new ArrayList<>();
Method method=list.getClass().getMethod("add",Object.class);
method.invoke(list,"Java 反射机制实例");
System.out.println(list.get(0));
}