题目
实现一个类型安全的泛型数组合并方法
信息
- 类型:问答
- 难度:⭐⭐
考点
泛型方法设计, 数组操作, 类型擦除处理, 边界通配符应用
快速回答
实现要点:
- 使用泛型方法声明:
<T> T[] mergeArrays(T[] a, T[] b) - 通过
Array.newInstance()创建运行时类型数组 - 使用
System.arraycopy高效复制数组 - 处理空数组和边界情况
问题背景
在Java中直接创建泛型数组存在类型擦除问题,需要特殊处理才能实现类型安全的数组合并。本题考察候选人处理泛型与数组结合时的实际能力。
解决方案
public class ArrayUtils {
public static <T> T[] mergeArrays(T[] a, T[] b) {
if (a == null) return b;
if (b == null) return a;
// 获取运行时类型创建新数组
Class<?> componentType = a.getClass().getComponentType();
T[] merged = (T[]) Array.newInstance(componentType, a.length + b.length);
System.arraycopy(a, 0, merged, 0, a.length);
System.arraycopy(b, 0, merged, a.length, b.length);
return merged;
}
}原理说明
- 类型擦除问题:Java泛型在编译后类型信息被擦除,无法直接使用
new T[] - Array.newInstance:通过反射获取运行时类型创建数组,保证类型安全
- System.arraycopy:本地方法实现高效数组复制
最佳实践
- 添加空指针检查:处理输入数组为null的情况
- 类型校验:可增加
b.getClass().getComponentType()与a的类型一致性检查 - 使用
@SafeVarargs注解消除警告
常见错误
| 错误写法 | 问题分析 |
|---|---|
T[] merged = (T[]) new Object[...] | 运行时实际类型为Object[],导致ClassCastException |
return Arrays.copyOf(...) | 底层仍依赖Array.newInstance,但需处理类型匹配 |
| 忽略空数组 | 未处理null输入导致NullPointerException |
扩展知识
- 边界通配符应用:若需合并子类型数组,可改为
<T> T[] mergeArrays(T[] a, T[] b) - 性能优化:对于基本类型数组,应提供重载方法(如mergeIntArrays)避免装箱开销
- Java 8+方案:使用Stream实现更简洁:
return Stream.concat(Arrays.stream(a), Arrays.stream(b)).toArray(size -> (T[]) Array.newInstance(a.getClass().getComponentType(), size));