当前位置: 首页 > 知识库问答 >
问题:

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

陆烨磊
2023-03-14

这是基于我的最后一个问题,为什么我会得到一个类强制转换异常(与泛型类似)?

这又是我的设计。我有一个抽象的超类AbstractArrayList和两个扩展它的具体子类sorted和UnsortedArrayList。

这里的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(类)未定义。有人知道问题是什么吗?我在AbstractArrayList的问题中定义了chrylis在类实例中提供的同一个构造函数。

共有3个答案

易和怡
2023-03-14

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

public AbstractArrayMyList(Class<E> clazz)
{
    elementData=(E[])Array.newInstance(clazz);
}
苗学民
2023-03-14

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

new EnumMap<>(KeyEnum.class)
单于智
2023-03-14

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

这适用于ArrayListSorted()构造函数。如果要保持ArrayListSorted为泛型(使用类型参数),则只能传递对象。如果要使其具体化,只需指定参数和类即可。

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

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);
  }
...

如您所见,当您指定类型参数...扩展ArrayListSorted

一种选择是,使用通用接口作为实现,这样您就可以:

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

 类似资料:
  • 我试图使一个用户类和使用类来处理登录,但从某种原因我的用户类构造函数是读取我的mysqli对象作为一个字符串 这是我的密码 Class.php mysql.php checklogin.php 它给了我这个错误 可捕获的致命错误:在第13行的C:\wamp\www\class.php中,类mysqli的对象无法转换为字符串 我要把头发拔出来了,有什么想法吗?

  • 我有一个java类,它只有静态方法和字段,所以我不想为此创建任何对象。我可以从两个方面来理解, 创建类摘要 使用私有构造函数。 这两种方法哪一种更好?

  • 我正在初始化的代码: 如何根据 类型在我的 函数中启动 ? ps-getForObject是spring restTemplate的标准函数-http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html#getForObject-java.lang.Str

  • 问题内容: 在Java中,在抽象类中使用私有构造函数的目的是什么? 在一个评论中,我得到了这个问题,我很好奇,在什么情况下我们需要以这种方式使用构造函数? 我认为它可以与抽象类中的另一个构造函数一起使用,但这非常简单。它也可以用于构造将超过抽象类的静态内部类。 也许还有更优雅的用法? 问题答案: 如果构造函数是类的 唯一 构造函数,则原因很明确:防止子类化。一些类仅充当静态字段/方法的持有者,而不

  • TypeScript中非抽象类(非抽象构造函数)的类型签名如下: 这也称为可更新类型。但是,我需要一个抽象类(抽象构造函数)的类型签名。我理解它可以定义为具有类型,但这太宽泛了。难道没有更精确的替代方案吗? 编辑: 为了阐明我的意思,下面的小片段演示了抽象构造函数和非抽象构造函数之间的区别: 类型'typeof实用程序'不能分配给类型'new(... args: any[])= 无法将抽象构造函数

  • 这里是Java新手。我有两个类(让我们称它们为A和B)和一些方法(例如...))它们包含的代码非常相似,因为它们实际上共享相同的代码。我决定让我的代码更有效,并使用某种父抽象类C,类A、B将继承它。 这是我的问题。方法 doSomething 在类 A 中具有以下签名: < code>doSomething(VievForA视图,...) 而B类中的相同方法do的签名如下: < code>doSo