通用数组 - 从Object []到T []的未经检查的强制转换

时间:2014-05-24 09:10:35

标签: java arrays generics casting

我是Java的新手,我已经阅读了一些关于类型转换的一般信息,这可能是我的问题的解决方案。 而且我认为我确实掌握了这个概念 - 比如,如果只有一种方法可以用于不同的类。但是我无法将它应用于我自己的通用数组代码,因为我不知道在哪个点上进行转换以及我需要通过哪个方法进行循环来发送整个数组?

这是我的mergesort算法,如果它不适用于泛型类型,它应该可以正常运行...

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));
}
}

非常感谢任何建议!

1 个答案:

答案 0 :(得分:0)

不幸的是,你无能为力。由于类型擦除,可以用来查看转换是否有效的类型信息会丢失,因此检查必须推迟到运行时,可以抛出ClassCastException,终止程序。由于编译器无法证明这种情况不会发生,因此会发出警告。


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

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

被删除到此:

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

由于Object未实现Comparable,演员表将失败。

解决方案是创建Comparable数组:

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