[英]Error with return-statement of generic type function
我試圖制作一個通用函數,將一個數組(int [],String [])傳遞給該函數,並使用TreeSort返回它的排序版本。 因為主類拒絕接受int []數組作為參數 ,所以我什至沒有機會對其進行調試。
TreeSort
public T[] treeSort(T[] arr) {
T[] result = (T[]) new Object[arr.length];
for (int i = 0; i < arr.length; i++)
if (arr[i] != null)
add(arr[i]);
Iterator it = iterator();
int count = 0;
while (it.hasNext())
result[count++] = (T) it.next();
return (T[]) result;
}
主要
BinarySearchTree<Integer> tree2 = new BinarySearchTree<>();
int[] unsortedNums = {6,3,7,4,1,2,9,8,5};
int[] sortedNums = tree2.treeSort(unsortedNums);
錯誤
BinarySearchTree類型的方法treeSort(Integer [])不適用於參數(int [])
因此,我嘗試將unsortedNums
和sortedNums
從int
更改為Integer
(為什么sortedNums
?),現在運行它會產生此錯誤:
錯誤2
線程“主”中的異常java.lang.ClassCastException:[Ljava.lang.Object; 無法轉換為[Ljava.lang.Comparable;
在線
T[] result = (T[]) new Object[arr.length];
在Java的通用方法中,不允許創建通用類型的數組。 您正在嘗試通過創建一個Object數組並將其強制轉換為通用類型來規避此規則,但是編譯器太聰明了,因此無法這樣做。 該規則的原因在於,泛型類型很可能是接口,因此運行時不知道要創建哪個類。
以您的示例為例,如果您確實需要按原樣保留未排序的數組並返回一個副本(通常,排序發生在原位,因此您只需編輯原始數組),則可以讓用戶傳遞通用類型(如sp00m的回答),或者讓用戶提供目標數組作為參數,因此您無需自己創建數組。
IMO,這里的最佳實踐是使您的排序發生在適當的位置,而不是返回數據的排序后的副本。
代替:
T[] result = (T[]) new Object[arr.length];
您必須使用:
T[] result = (T[]) Array.newInstance(clazz, arr.length);
其中clazz
是嵌套元素的類型:
public T[] treeSort(T[] arr, Class<T> clazz) {...}
最后,在調用時,使用裝箱的原語:
Integer[] unsortedNums = { 6, 3, 7, 4, 1, 2, 9, 8, 5 };
Integer[] sortedNums = treeSort(unsortedNums, Integer.class);
在Java中,數組在運行時知道其組件類型(組件類型是實際運行時數組類型的一部分),因此您需要在運行時指定組件類型以創建該類型的數組。
@spoom的答案向您展示了如何在傳遞給函數的類對象下創建數組。 但是,您實際上已經擁有該信息,而沒有單獨傳遞它。 參數arr
為T[]
類型,這意味着數組對象的實際運行時類型必須為T[]
或其子類。 我們可以從中提取組件類型並使用它來創建新的數組:
T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);
例如,這就是Arrays.copyOf()
和相關函數的工作方式。
您不能在泛型中使用基本類型(int)。 例如,嘗試使用對象包裝器
Integer[] unsortedNums = {6,3,7,4,1,2,9,8,5}; Integer[] sortedNums = tree2.treeSort(unsortedNums);
在Java中,將泛型和數組結合起來是有問題的。 查看文章通用限制 。
對於解決問題,最簡單的方法不是使用數組,而是使用列表。 因此,例如:
public List<T> treeSort(List<T> list) {
List<T> result = new ArrayList<T>(list.size());
for (int i = 0; i < list.size(); i++)
if (list.get(i) != null)
result.add(list.get(i));
Iterator<T> it = list.iterator();
int count = 0;
while (it.hasNext())
result.set(count++, it.next());
return result;
}
提醒您,我尚未測試邏輯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.