Java泛型SortedListArray类ClassCastException异常解决求助
泛型SortedListArray类的ClassCastException问题解决
问题场景
实现了基于数组的泛型排序列表类SortedListArray<T extends Comparable<T>>,实例化代码如下:
private SortedListArray<Integer> ArraySortedListInt; ArraySortedListInt = new SortedListArray<Integer>(sortedArray.length);
抛出异常:
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.Comparable; ([Ljava.lang.Object; and [Ljava.lang.Comparable; are in module java.base of loader 'bootstrap')
尝试使用Array.newInstance的构造器仍未解决问题。
错误原因
Java泛型存在类型擦除机制:编译时泛型类型T会被擦除为上界Comparable<T>,运行时elements变量的实际类型会被视为Comparable[]。但原构造器中创建的是Object[],强转成T[]只是编译期的语法糖,运行时Object[]无法直接转换成Comparable[],因此抛出类型转换异常。
你尝试的Array.newInstance构造器只覆盖了部分场景,且调用时未传入正确的Class对象,因此无法解决问题。
解决方案
方案1:基于Comparable数组实现(推荐,无需传入Class对象)
利用T的上界是Comparable<T>,直接创建Comparable[]数组再强转成T[],这样运行时数组的实际类型与类型擦除后的类型匹配:
public class SortedListArray<T extends Comparable<T>> { private final int DEFCAP = 20; private T[] elements; private int numElements; // 其他成员变量省略 public SortedListArray() { // 创建Comparable数组,强转成T[] elements = (T[]) new Comparable[DEFCAP]; numElements = 0; } public SortedListArray(int customCap) { elements = (T[]) new Comparable[customCap]; numElements = 0; } // 修复find方法的两个逻辑错误 private void find(T element) { isFound = false; location = 0; int mid; int low = 0; // 修正:实际元素的上限是numElements-1,不是数组容量的上限 int high = numElements - 1; while (low <= high) { mid = (low + high) / 2; // 避免访问未填充的null元素 if (elements[mid] == null) { high = mid - 1; continue; } int compareResult = elements[mid].compareTo(element); if (compareResult == 0) { isFound = true; location = mid; return; } else if (compareResult < 0) { // 修正:当前元素小于目标,去右半部分查找 low = mid + 1; } else { high = mid - 1; } } } // 其他方法省略 }
方案2:正确使用Array.newInstance(需传入Class对象)
如果需要创建具体类型的数组,需在实例化时传入Class<T>,并修改所有构造器:
public class SortedListArray<T extends Comparable<T>> { private final int DEFCAP = 20; private T[] elements; private int numElements; // 其他成员变量省略 public SortedListArray(Class<T> clazz) { elements = (T[]) Array.newInstance(clazz, DEFCAP); numElements = 0; } public SortedListArray(Class<T> clazz, int customCap) { elements = (T[]) Array.newInstance(clazz, customCap); numElements = 0; } // 其他方法省略 }
调用方式:
private SortedListArray<Integer> ArraySortedListInt; ArraySortedListInt = new SortedListArray<Integer>(Integer.class, sortedArray.length);
额外修复点
原代码的find方法存在两个逻辑错误:
high初始值误用elements.length-1,数组容量可能大于实际元素数,应改为numElements-1,避免访问null元素抛出NullPointerException。- 二分查找方向错误:当
elements[mid].compareTo(element) < 0时,目标元素在右半部分,应设置low = mid + 1,原代码设置high = mid -1会导致查找范围丢失。
内容的提问来源于stack exchange,提问作者Aman Savaria
相关产品推荐
相关产品推荐

