繁体   English   中英

如何将类名传递给抽象超类构造函数?

[英]How to pass in a class name in to abstract superclass constructor?

这是基于我的最后一个问题, 为什么我会收到类强制转换异常(具有泛型,可比)?

这又是我的设计。 我有一个抽象超类AbstractArrayList和两个扩展它的具体子类,即已排序和未排序的数组列表。

这是AbstractArrayList,它管理实际数据,因为它需要已实现的方法。

public abstract class AbstractArrayMyList<E> implements MyList<E> {
        protected E[] elementData;
       .....
}

这是ArrayListSorted的声明,它扩展了AbstractArrayMyList

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> 

以及导致异常的测试代码行

    ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>()
    toTestInteger.insert(0);
    assertEquals(toTestInteger.get(0).intValue(), 0);

和实际的异常本身

java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable;
    at myarraylist.ArrayListSorted.getIndex(ArrayListSorted.java:38)

ArrayListSorted-此方法内包含Java第38行

public int getIndex(E value) {
      ....
     line 38 - if      (value.compareTo(elementData[mid]) < 0)  hi = mid - 1;

我从问题中得到的答复阐明了异常是由什么引起的。 当我尝试拨打此电话时

value.compareTo(elementData[mid]) < 0

值的类型正确,因为扩展部分会将类型对象范围缩小为可比较类型。 但是,运行Java字节码的JVM仅将elementData数组识别为对象数组,因此当我尝试将elementData [mid]转换为Comparable时,它实际上不是Comparable类型。

chrylis在另一个问题中给我的解决方案是在AbstractArrayList中有一个构造函数,该构造函数将构造正确的类型化数组

protected AbstractArrayMyList(Class<E> clazz) {
        this.elementClass = clazz;
        this.elementData = Array.newInstance(clazz, INITIAL_SIZE);
}

我试图在我的排序数组列表子类中调用此构造函数,

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> 
       public ArrayListSorted() {
             super(Class.forName(("E"));
        }
   ...

我从该线程获得的语法- 将类作为参数传递给Java中的方法

但是我遇到了编译器错误-构造函数AbstractArrayMyList(Class)未定义。 有人知道这个问题是什么吗? 我定义了与chrylis在我的问题中的AbstractArrayList中提供给我的同一个构造函数,该构造函数接受一个类实例。

如果需要Parameter的具体类,则必须指定它。 无法从类型参数E派生它。

这适用于ArrayListSorted()构造函数。 如果要保持ArrayListSorted通用(带有Parameter类型),则只能传递Class对象。 如果要使其特定,则只需指定参数和类。

在这种情况下,我将使用一个具体的类名称,例如:

public class ArrayListSorted<E extends Comparable<E>>
  extends AbstractArrayMyList<E> {
   public ArrayListSorted(Class<E> cls) {
         super(cls);
    }
...

public IntArrayListSorted extends ArrayListSorted<Integer> {
  public IntArrayListSorted() {
    super(Integer.class);
  }
...

如您所见,当您指定类型参数( ... extends ArrayListSorted<Integer> )时,它将被定义为Integer,然后构造函数还需要Class<Integer> :( super(Integer.class) )。

一种选择是,使用公共接口作为实现,因此您可以:

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<Comparable>
{
    public ArrayListSorted()
    {
        super(Comparable.class);
    }
}

不,不是字面上的E ,而是您用于E的类。 请参见EnumMap的构造函数:

new EnumMap<>(KeyEnum.class)

您收到错误“构造函数AbstractArrayMyList(Class)未定义”,因为您没有这样的构造函数。

public AbstractArrayMyList(Class<E> clazz)
{
    elementData=(E[])Array.newInstance(clazz);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM