簡體   English   中英

泛型類型實現接口時,無法將 Object 數組強制轉換為泛型類型數組

[英]Can't cast array of Object to array of generic type when generic type implements interface

我正在用 Java 實現一個 Quicksort 類。 為了使排序起作用,要排序的項目需要具有可比性,例如通過實現Comparable接口。 但是,在運行時在返回數組切片的方法中進行轉換時,實現Comparable會給我帶來問題:

public class QuickSorter<T extends Comparable<T>> {

    ...

    private T[] sliceOfArray(T[] arr, int start, int end) {
        Object[] slice = new Object[end - start];

        for (int i = start; i < end; i++) {
            slice[i] = arr[i];
        }

        return (T[]) slice; // Throws exception at runtime.
    }
}

例外是:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
    at com.sortingalgos.QuickSorter.sliceOfArray(QuickSorter.java:55)
    at com.sortingalgos.QuickSorter.sort(QuickSorter.java:11)
    at com.sortingalgos.MainApp.main(MainApp.java:11)

我怎樣才能解決這個問題?

簡單的解決方法是改變這一行

    Object[] slice = new Object[end - start];

    Comparable[] slice = new Comparable[end - start];

轉換為T[]的業務是一種黑客行為。 它實際上並沒有改變數組的類型。 您不想假裝它確實輸入正確而傳遞它。 使用Object[] (或Comparable[] )或簡單的舊List<T>可能更清楚。

您甚至無法執行以下操作:

        Object[] a = new Object[] {1,3,4,5};
        Integer[] b = (Integer[])a;
        System.out.println(Arrays.toString(b));

這是因為不能保證Object[] a看起來不像下面這樣:

      Object[] a = new Object[]{1,3,4,5.7}

這顯然不是整數數組。 但是你可以這樣做。

        Object[] a = new Integer[] {1,3,4,5};
        Integer[] b = (Integer[])a;
        System.out.println(Arrays.toString(b));


問題是Object數組不是Comparable數組。 您需要slice數組與arr數組具有相同的元素類型。 你可以通過改變來實現這一點

Object[] slice = new Object[end - start];

T[] slice = java.lang.reflect.Array.newInstance(arr.class.getComponentType(), end - start);

換句話說,使用反射在運行時確定元素類型,並創建相同類型的切片數組。

然而,使用反射的性能可能較低。 對於像 QuickSort 這樣的就地排序算法,您根本不需要創建任何新數組,您可以只使用輸入數組。 (或者克隆它,如果你不允許修改輸入。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM