Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么我会遇到类强制转换异常?_Java_Arrays_List_Generics_Arraylist - Fatal编程技术网

Java 为什么我会遇到类强制转换异常?

Java 为什么我会遇到类强制转换异常?,java,arrays,list,generics,arraylist,Java,Arrays,List,Generics,Arraylist,我有两个类,AbstractArrayMyList类和一个ArrayListSorted类,它扩展了AbstractArrayMyList 下面是我对AbstractArrayMyList和相关构造函数的声明 public abstract class AbstractArrayMyList<E extends Comparable<E>> implements MyList<E> { private static final int DEFAULT

我有两个类,AbstractArrayMyList类和一个ArrayListSorted类,它扩展了AbstractArrayMyList

下面是我对AbstractArrayMyList和相关构造函数的声明

public abstract class AbstractArrayMyList<E extends Comparable<E>> implements MyList<E>  {
    private static final int DEFAULT_CAPACITY = 100; 
    protected E[] elementData;
    public AbstractArrayMyList() {
            this( DEFAULT_CAPACITY);
    }
    public AbstractArrayMyList( int capacity) {
           elementData = (E[]) new Object[capacity];
    }
公共抽象类AbstractArrayMyList实现MyList{
专用静态最终int默认_容量=100;
受保护的E[]元素数据;
公共抽象ArrayMyList(){
这(默认容量);
}
公共抽象ArrayMyList(内部容量){
elementData=(E[])新对象[容量];
}
MyList是adt接口

和我的ArrayListSorted类(带有相关构造函数)

公共类ArrayListSorted扩展
抽象数组列表{
公共ArrayListSorted(){
超级();
}
}
下面是导致类强制转换异常的一行代码。(只是创建了一个数组列表,排序类的类型为有界整数。我真的不明白为什么会发生这种异常。)

ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>();
ArrayListSorted toTestInteger=new ArrayListSorted();
chrylis在这里解释说,问题在于jvm将我的新对象[capacity]视为一个对象数组。我同意这一点,但当时AbstractArrayMyList的定义仍然是

public abstract class AbstractArrayMyList<E> implements MyList<E>   
公共抽象类AbstractArrayMyList实现MyList

,这意味着jvm必须将E视为on对象,因为它对它一无所知。但是,既然我添加了E,那么不应该允许这种转换吗?jvm会将其识别为可比较对象的数组吗?

如果jvm允许,您可以将E以外的对象放入,比如String,当您检索Obj时ect您假设它是E,并将其强制转换为E,这将在运行时导致ClassCastException。泛型完全防止这种情况,在编译时检测尽可能多的故障。

问题是对象不可比较。因此,在抽象类的构造函数中创建数组失败

您可以通过删除抽象声明中的
Comparable
部分来解决此问题:

 public abstract class AbstractArrayMyList<E> implements MyList<E>  {
   ...

}
然后,您的所有排序都将起作用:

例如,主要方法如下:

public static void main(String... args){
    ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>();

    toTestInteger.add(5);
    toTestInteger.add(2);
    System.out.println(toTestInteger.get(0));
    System.out.println(toTestInteger.get(1));
(假设抽象类中的add()代码使用数组)

更新2

如果要在子类中排序,则必须对抽象类进行一些小的更改

最简单的方法是让抽象类通过构造函数获得传入的数组,这样子类就形成了数组的类型

public abstract class AbstractArrayMyList<E> implements List<E>  {
    protected E[] elementData;
    int size=0;

    protected AbstractArrayMyList(E[] elementData) {
         this.elementData = elementData;
    }

    ....

 }
公共抽象类AbstractArrayMyList实现列表{
受保护的E[]元素数据;
int size=0;
受保护的AbstractArrayMyList(E[]elementData){
this.elementData=elementData;
}
....
}
然后在子类中,执行默认容量操作,然后调用父类的构造函数,传入已构造的正确类型的数组

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> {
     private static final int DEFAULT_CAPACITY = 100; 

     public ArrayListSorted(){
         this(DEFAULT_CAPACITY);
     }

     @SuppressWarnings("unchecked")
    public ArrayListSorted(int initialSize){
           //call parent constructor passing in new array
        super((E[]) new Comparable[initialSize]);
    }

...
公共类ArrayListSorted扩展了AbstractArrayMyList{
专用静态最终int默认_容量=100;
公共ArrayListSorted(){
这(默认容量);
}
@抑制警告(“未选中”)
公共ArrayListSorted(int initialSize){
//调用传递新数组的父构造函数
超级((E[])新可比[初始值];
}
...

现在代码又正常工作了

,因此整数被作为E放入,然后当它被检索时,它就不能被回滚了?@CommittedRoider,如果JVM允许您这样做,是的。但是E可以是任何对象类型,包括String@committedandroiderE可以是实现Compariable的任何对象一个作为字符串也实现了Comparable。让我们来看看没有实现Comparable的Process、Thread或Random类。因此,如果检索实现Comparable的元素E,就不能将其转换为Random或Process,因为它们不可比较?我也尝试过,但问题是AbstractArrayMyList正在工作使用包含不一定可比较元素的elementData数组,因为E在AbstractArrayMyList中未实现可比较谢谢:)))未排序的数组与可比较的类型一起工作并不重要?这取决于排序的位置。您是在抽象类中排序还是在子类中排序?如果是抽象类,则所有子类都必须使用可比较的
E
。如果在子类中排序,则返回到相同的问题或问题数组的类型错误。再次更新了答案,提供了如何仅处理子类排序的解决方案仅在子类排序数组中排序,而不是未排序数组中排序
public static void main(String... args){
    ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>();

    toTestInteger.add(5);
    toTestInteger.add(2);
    System.out.println(toTestInteger.get(0));
    System.out.println(toTestInteger.get(1));
2
5
public abstract class AbstractArrayMyList<E> implements List<E>  {
    protected E[] elementData;
    int size=0;

    protected AbstractArrayMyList(E[] elementData) {
         this.elementData = elementData;
    }

    ....

 }
public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> {
     private static final int DEFAULT_CAPACITY = 100; 

     public ArrayListSorted(){
         this(DEFAULT_CAPACITY);
     }

     @SuppressWarnings("unchecked")
    public ArrayListSorted(int initialSize){
           //call parent constructor passing in new array
        super((E[]) new Comparable[initialSize]);
    }

...