Java中如何获取泛型T的包装类型(基本类型返回包装类否则返回自身)
结论
Java语法层面不存在直接实现“泛型T为基本类型时自动返回对应包装类型、否则返回T本身”的机制,根本原因是Java泛型的类型参数只支持引用类型,T永远不可能是int/long这类基本类型。
你传入new int[10]时,int[]本身是引用类型(数组是Java对象),此时泛型T会被推断为int[],要求传入的比较器类型为Comparator<int[]>,和你提供的Comparator<Integer>完全不匹配,因此编译失败。
可行的实现方案
方案1:重载对应基本类型的排序方法(推荐)
这是最常用、类型安全且无额外性能开销的方案,为每一种需要支持的基本类型数组编写单独的重载方法:
// 原有对象数组排序方法 public static <T> void sort(T[] a, java.util.Comparator<T> c) { // ...原有排序逻辑 } // int数组重载版本 public static void sort(int[] a, java.util.Comparator<Integer> c) { // 实现逻辑:排序过程中自动拆装箱调用compare方法即可 int n = a.length; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { // 自动装箱int为Integer调用比较器 if (c.compare(a[i], a[j]) > 0) { int temp = a[i]; a[i] = a[j]; a[j] = temp; } } } }
其他基本类型(long、double等)参考int数组的写法实现即可,你问题中编译失败的代码就可以正常运行。
方案2:通用反射适配方案
如果不想为每个基本类型写重载,可以通过反射自动识别数组的基本类型,转换为对应包装类数组后再排序,适合需要适配所有基本类型且能接受少量性能开销的场景:
// 通用入口方法 public static <T> void sort(Object array, java.util.Comparator<T> c) { if (!array.getClass().isArray()) { throw new IllegalArgumentException("第一个参数必须为数组类型"); } Class<?> componentType = array.getClass().getComponentType(); int length = java.lang.reflect.Array.getLength(array); // 基本类型数组自动转包装类数组 if (componentType.isPrimitive()) { Class<T> wrapperType = (Class<T>) getWrapperType(componentType); T[] wrappedArray = (T[]) java.lang.reflect.Array.newInstance(wrapperType, length); for (int i = 0; i < length; i++) { wrappedArray[i] = (T) java.lang.reflect.Array.get(array, i); } // 调用对象数组排序逻辑 sort(wrappedArray, c); // 排序结果写回原基本类型数组 for (int i = 0; i < length; i++) { java.lang.reflect.Array.set(array, i, wrappedArray[i]); } return; } // 对象数组直接调用原有排序逻辑 sort((T[]) array, c); } // 基本类型转对应包装类工具方法 private static Class<?> getWrapperType(Class<?> primitiveType) { if (primitiveType == int.class) return Integer.class; if (primitiveType == long.class) return Long.class; if (primitiveType == double.class) return Double.class; if (primitiveType == float.class) return Float.class; if (primitiveType == boolean.class) return Boolean.class; if (primitiveType == char.class) return Character.class; if (primitiveType == byte.class) return Byte.class; if (primitiveType == short.class) return Short.class; throw new IllegalArgumentException("不支持的基本类型:" + primitiveType.getName()); }
该方案的缺点是编译期无法校验数组类型和比较器的类型匹配,类型错误只会在运行时抛出。
内容的提问来源于stack exchange,提问作者Alexey Ismagilov
相关产品推荐
相关产品推荐

