java在抽象基类构造函数调用该抽象方法_关于Java:如何将类名传递给抽象超类构造函数?...

这是基于我的最后一个问题

为什么我会收到类强制转换异常(具有泛型,可比)?

这又是我的设计。

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

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

public abstract class AbstractArrayMyList implements MyList {

protected E[] elementData;

.....

}

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

public class ArrayListSorted> extends AbstractArrayMyList

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

ArrayListSorted toTestInteger = new ArrayListSorted()

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 clazz) {

this.elementClass = clazz;

this.elementData = Array.newInstance(clazz, INITIAL_SIZE);

}

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

public class ArrayListSorted> extends AbstractArrayMyList

public ArrayListSorted() {

super(Class.forName(("E"));

}

...

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

但是我遇到了编译器错误-构造函数AbstractArrayMyList(Class)未定义。

有人知道这个问题是什么吗?我定义了与chrylis在我的问题中提供给我的类实例的构造函数相同的构造函数。

嗯,我认为Class.forName(" E")是错误的,还是您有这样的课程? 这必须是现有的。 在您的情况下,您很可能希望将类参数设为ArrayListSorted(Classcls) { super(cls);}。 我认为您的编译错误是因为Class.forName(..)`` returns Class `不是Class

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

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

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

public class ArrayListSorted>

extends AbstractArrayMyList {

public ArrayListSorted(Class cls) {

super(cls);

}

...

public IntArrayListSorted extends ArrayListSorted {

public IntArrayListSorted() {

super(Integer.class);

}

...

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

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

public class ArrayListSorted> extends AbstractArrayMyList

{

public ArrayListSorted()

{

super(Comparable.class);

}

}

因此,这种方式的数组将是Integer或其他类型,而不是String

我选择Integer作为示例,因为您在上面的代码中使用了Integer。 但是您可以使用任何Comparable类。 我不认为这是"而不是字符串"-字符串未在任何地方使用?

我说的是任何通用类型。

当您构造一个数组列表排序的类时,我不希望客户端显式传递类对象,就像ArrayListSorted array = new ArrayListSorted ();一样。

@committedandroider我添加了一个使用Interface作为元素类型的选项。

您收到错误"构造函数AbstractArrayMyList(Class)未定义"

因为您没有这样的构造函数。

public AbstractArrayMyList(Class clazz)

{

elementData=(E[])Array.newInstance(clazz);

}

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

new EnumMap<>(KeyEnum.class)

对我来说,传入E是有意义的,它实现了与抽象排序列表相当的功能。 我不知道您在这种情况下如何使用枚举映射

@committedandroider我只是将其显示为该惯用法的示例。

整数说,我该如何传递E扩展可比较的类呢?

@committedandroider Integer.class?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值