MST

星途 面试题库

面试题:Java泛型之类型擦除理解

请阐述Java泛型中的类型擦除机制是什么,以及它会对代码产生哪些影响,举例说明。
16.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

类型擦除机制

Java泛型的类型擦除指的是,在编译阶段,所有的泛型类型信息都会被擦除掉。编译器在编译带有泛型的代码时,会将泛型类型替换为它们的限定类型(通常是Object,如果有上限则替换为上限类型)。例如,对于List<String>,在编译后实际的类型会被擦除为List,其中String类型信息被去除。

对代码产生的影响

  1. 无法在运行时获取泛型类型信息:由于类型信息在编译后被擦除,运行时无法确切知道泛型的实际类型。例如:
List<String> list = new ArrayList<>();
list.add("Hello");
// 以下代码无法获取到泛型参数String的实际类型
Type type = list.getClass().getGenericSuperclass(); 
  1. 可能导致编译警告:当使用了未经检查的泛型操作时,编译器会发出警告。比如将一个List赋值给List<String>
List list = new ArrayList();
list.add(123);
List<String> stringList = list; // 这里会产生未经检查的转换警告
String str = stringList.get(0); // 运行时会抛出ClassCastException
  1. 泛型方法和泛型类的桥接方法:在涉及到泛型的继承和多态时,编译器会生成桥接方法来保持多态的正确性。例如:
class GenericBase<T> {
    public T get(T t) { return t; }
}
class GenericSub extends GenericBase<String> {
    @Override
    public String get(String t) { return t; }
}

在编译后,为了保证多态,编译器会为GenericSub生成一个桥接方法:

public Object get(Object t) {
    return get((String) t);
}
  1. 无法创建泛型数组:由于类型擦除,不能直接创建泛型数组。例如:
// 以下代码会编译错误
T[] array = new T[10]; 

因为编译后T被擦除,实际类型不确定,所以不能创建这样的数组。