簡體   English   中英

泛型類中的Java泛型轉換

[英]java generic casting in generic classes

我正在編寫一個通用max堆的簡單實現。 如果我寫

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

它編譯。 現在要實際實現堆,即編寫maxHeapify(),我需要能夠比較兩個T。 先驗似乎可行的一種選擇是告訴編譯器T實現Comparable。 但是,如果我用<T實現Comparable>來替換<T>,編譯器會抱怨-我該怎么做?

另外,我可以定義一個類

public class HasValue{

  int value;

  public HasValue(int value){
        this.value = value;
  }

}

從理論上講,我應該能夠比較兩個HasValue對象,例如x.value> y.value。 但是如果我輸入

public class FastMaxHeap<T extends HasValue>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(){
    data = (T[]) new Object[HEAP_SIZE];
  size = 0;
  }
}

我現在得到一個ClassCastException。 這里發生了什么? Java泛型傷害了我的大腦。

在第一種情況下, T extends Object ,該Object在運行時被擦除為Object

在第二種情況下, T extends HasValue擦除為HasValue因此您需要擁有。

data = (T[]) new HasValue[HEAP_SIZE];

恕我直言,Java不允許new T[HEAP_SIZE]來做您必須做的事情,這是不必要的。

您可以嘗試這一步(尚未編譯)

public class FastMaxHeap<T extends HasValue>{

  HasValue[] data;
  int size;

  static final int HEAP_SIZE = 10000;

   public FastMaxHeap(){
     data = new HasValue[HEAP_SIZE];
     size = 0;
   }
}

最好有類型標記來創建這樣的數組

public class FastMaxHeap<T>{

  T[] data;
  int size;

  static final int HEAP_SIZE = 10000;

  @SuppressWarnings("unchecked")
  public FastMaxHeap(Class<T> clazz){
    data = (T[])Array.newInstance(clazz, HEAP_SIZE);
    size = 0;
  }
}

這樣,您將在運行時沒有ClassCastExceptions

而且: < T implements Comparable >不正確,正確的是< T extends Comparable >

您的堆應接受Comparator <T>作為構造函數參數。 問題解決了。 客戶可以使用他想要的任何類型。 您還可以提供一個簡單的重載,它推斷已經實現Comparable的T類型的比較器實現。

暫無
暫無

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

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