【问题标题】:Generic array - Unchecked cast from Object[] to T[]通用数组 - 从 Object[] 到 T[] 的未经检查的强制转换
【发布时间】:2014-05-24 09:10:35
【问题描述】:

我对 Java 很陌生,我已经阅读了一些关于类型转换的一般信息,这可能是我的问题的解决方案。 而且我认为我确实掌握了这个概念 - 就像一个人想要使用的一种方法是为不同的班级制作的。但是我无法将它应用到我自己的带有泛型数组的代码中,因为我不知道在哪个点进行转换以及使用哪种方法,或者我是否必须创建一个循环来发送整个数组?

这是我的归并排序算法,如果不是泛型类型,它应该可以正常工作......

package src;

import java.util.Arrays;

public class MergeSort {

// sort array of type T using the Mergesort algorithm
public static <T extends Comparable<T>> T[] sort(T[] arr) {

            @SuppressWarnings("unchecked")
    T[] leftArray = (T[]) new Comparable[12]; // ERROR: Type safety: Unchecked cast from 
 // Object[] to T[]
    @SuppressWarnings("unchecked")
            T[] rightArray =(T[]) new Comparable[12]; // ERROR: Type safety: Unchecked cast from 
 // Object[] to T[]

    if (arr.length > 1) {


        int half = arr.length / 2;

        leftArray = Arrays.copyOfRange(arr, 0, half);
        rightArray = Arrays.copyOfRange(arr, half + 1, arr.length);

    }
    return merge( sort(leftArray), sort(rightArray));
}

private static <T extends Comparable<T>> T[] merge(T[] leftArray, T[] rightArray) {
            @SuppressWarnings("unchecked")
    T[] tempArray = (T[]) new Comparable[12];   // ERROR: Type safety: Unchecked cast from 
 // Object[] to T[]
     int i = 0;
     int leftIndex = 0;
     int rightIndex = 0; 

    while ( leftIndex < leftArray.length ||  rightIndex < rightArray.length ) {
        if ( leftIndex < leftArray.length && rightIndex < rightArray.length ) {
            if (leftArray[leftIndex].compareTo(rightArray[rightIndex]) < 0 )  {
                 tempArray[i] = leftArray[leftIndex] ;
                 leftIndex++; 
            }
            else {
                 tempArray[i] = rightArray[rightIndex] ;
                 rightIndex++; 
            }
        }
        else if ( leftIndex < leftArray.length ) {
                tempArray[i] = leftArray[leftIndex] ;
                leftIndex++; 
        }       
        else if ( rightIndex < rightArray.length ) {
            tempArray[i] = rightArray[rightIndex] ;
            rightIndex++;   

        }           
    } // end while  

    return tempArray;
}


public static void main(String[] args) {

    // Edit this line to check with different values for the array
    // or add more unit tests to test/MergeSortTest.java

    // // sort list of Characters
    Character[] charArr = { 'H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r',
            'l', 'd', '!' };

    charArr = MergeSort.<Character> sort(charArr);
    System.out.println(Arrays.toString(charArr));

    // sort list of Integers
    Integer[] intArr = { 23, 4, 15, 8, 42, 16 };

    intArr = MergeSort.<Integer> sort(intArr);
    System.out.println(Arrays.toString(intArr));
}
}

非常感谢任何建议!

【问题讨论】:

    标签: java arrays generics casting


    【解决方案1】:

    很遗憾,您对此无能为力。由于类型擦除,可用于查看强制转换是否有效的类型信息丢失了,因此必须将检查推迟到运行时,在运行时可能会抛出 ClassCastException,从而终止您的程序。由于编译器无法证明这不会发生,因此它会发出警告。


    还有一件事——你的代码无论如何都会失败。类型被擦除为其边界类型,在本例中为Comparable。因此,代码如下:

    T[] leftArray = (T[]) new Object[12];
    

    被抹去:

    Comparable[] leftArray = (Comparable[]) new Object[12];
    

    而且因为Object 没有实现Comparable,所以转换会失败。

    解决方案是改为创建Comparable 数组:

    T[] leftArray = (T[]) new Comparable[12];
    

    【讨论】:

    • 或者改用ArrayLists 并且没有任何演员表。
    • 有什么区别?您可以使用Arrays.sort(),甚至不需要列表。据我了解,OP 正在尝试将排序算法作为练习来实现。我看不出使用集合会如何干扰手头的任务。
    • @Tom 没什么。您可能是对的,因为这是一个练习,并且在功能上操作数组与 ArrayLists 之间没有区别,除非它是作业的一部分,或者如果性能是一个问题。
    • @user3580294 非常感谢您的快速帮助。至少编译器现在开始工作了!新问题是:return merge( sort(leftArray), sort(rightArray)); 行有问题,我觉得这很令人困惑,因为 sortmerge 两种方法都在 src.MergeSort.sort(MergeSort.java):23)` 处扩展到 Comparables知道为什么会这样,eclipse 并没有在该行标记任何内容,而是一直抱怨从 Object[] 到 T[] 的未检查。
    • @Tom 很遗憾,我们不允许使用列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 2022-02-03
    • 2013-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多