面试题答案
一键面试误区一:在运行时无法获取泛型类型信息
- 举例
public class GenericTest<T> { private T value; public void setValue(T value) { this.value = value; } public T getValue() { return value; } public static void main(String[] args) { GenericTest<Integer> intTest = new GenericTest<>(); intTest.setValue(10); // 这里无法在运行时获取到泛型参数T是Integer类型 // 因为类型擦除,运行时T被擦除为Object Class<?> type = intTest.getClass().getGenericSuperclass(); System.out.println(type); } }
- 解决方案
- 可以通过传递
Class
对象的方式来获取类型信息。修改代码如下:
public class GenericTest<T> { private T value; private Class<T> type; public GenericTest(Class<T> type) { this.type = type; } public void setValue(T value) { this.value = value; } public T getValue() { return value; } public static void main(String[] args) { GenericTest<Integer> intTest = new GenericTest<>(Integer.class); intTest.setValue(10); Class<?> type = intTest.type; System.out.println(type); } }
- 可以通过传递
误区二:泛型数组创建问题
- 举例
public class GenericArrayTest { public static void main(String[] args) { // 以下代码会编译错误 // 因为类型擦除,无法创建泛型数组 // List<String>[] listArray = new ArrayList<String>[10]; } }
- 解决方案
- 可以使用
ArrayList
等集合来代替泛型数组,或者创建通配符数组然后进行强制类型转换(但需要谨慎使用,因为存在类型安全风险)。例如:
@SuppressWarnings("unchecked") public class GenericArrayTest { public static void main(String[] args) { Object[] objectArray = new Object[10]; List<String>[] listArray = (List<String>[]) objectArray; // 使用时需注意类型安全,避免运行时错误 } }
- 可以使用
误区三:泛型方法重载问题
- 举例
public class GenericOverloadTest { public static <T> void print(T t) { System.out.println("普通泛型方法:" + t); } // 以下方法编译错误,因为类型擦除后,两个方法签名相同 // public static <E> void print(E e) { // System.out.println("另一个普通泛型方法:" + e); // } public static void main(String[] args) { print("Hello"); } }
- 解决方案
- 改变方法签名,例如增加参数或者修改返回类型等。比如:
public class GenericOverloadTest { public static <T> void print(T t) { System.out.println("普通泛型方法:" + t); } public static <E> int print(E e, int num) { System.out.println("另一个泛型方法:" + e); return num; } public static void main(String[] args) { print("Hello"); print("World", 10); } }