繁体   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