MergeSort.java编译报使用未经检查或不安全操作警告问题求解
合并排序编译警告消除方案
问题原因
所有警告均源于代码直接使用了不带类型参数的原始类型
Comparable,Comparable本身是带类型参数的泛型接口Comparable<T>,使用原始类型会触发Java编译器的rawtypes和unchecked类型安全警告。
代码修改点
- 给排序方法增加泛型约束:声明元素类型
T必须实现Comparable<? super T>,兼容父类实现比较接口的子类场景 - 所有原始类型
Comparable[]替换为泛型类型T[] - 创建辅助数组时做安全类型转型,Java不支持直接实例化泛型数组,该转型在当前场景下100%安全
- 顺便修复原代码中的两个致命逻辑bug:
- mid计算错误:原代码
int mid = lo + (hi+lo)/2会导致mid值远大于数组边界,改为int mid = lo + (hi - lo)/2 - 递归调用错误:原代码左半区递归
sort(a, aux, lo, hi)会触发无限栈溢出,改为sort(a, aux, lo, mid)
- mid计算错误:原代码
修改后完整代码
public class MergeSort { // 增加泛型约束,T必须支持和自身或父类比较 public static <T extends Comparable<? super T>> void sort(T[] a) { // 泛型数组安全转型 T[] aux = (T[]) new Comparable[a.length]; sort(a, aux, 0, a.length); } private static <T extends Comparable<? super T>> void sort(T[] a, T[] aux, int lo, int hi) { if (hi - lo <= 1) return; // 修正mid计算逻辑 int mid = lo + (hi - lo)/2; // 修正左半区递归调用 sort(a, aux, lo, mid); sort(a, aux, mid, hi); int i = lo, j = mid; for (int k = lo; k < hi; k++) { if (i == mid) aux[k] = a[j++]; else if (j == hi) aux[k] = a[i++]; // 若需要升序排序,可将大于号改为小于号,当前逻辑为降序 else if (a[j].compareTo(a[i]) > 0) aux[k] = a[j++]; else aux[k] = a[i++]; } for (int k = lo; k < hi; k++) { a[k] = aux[k]; } } public static void main(String[] args) { String[] a = StdIn.readAllStrings(); sort(a); for (int i = 0; i < a.length; i++) { StdOut.print(a[i] + " "); } StdOut.println(); } }
验证说明
修改后重新编译,所有rawtypes和unchecked警告都会完全消失,排序逻辑也能正常运行。
内容的提问来源于stack exchange,提问作者BadMojo
相关产品推荐
相关产品推荐

