2015-01-19 2 views
3

У меня есть два класса, класс 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]; 
    } 

с MyList быть АДТ интерфейса

, и моему ArrayListSorted класса (с соответствующим конструктору),

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

Вот является строка кода, вызывающая исключение класса. (Только создание списка массив отсортированный класса с ограниченным типа Integer. Im действительно путают о том, почему это исключение происходит.

ArrayListSorted<Integer> toTestInteger = new ArrayListSorted<Integer>(); 

chrylis объяснил здесь, Why am i getting a class cast exception(with generics, comparable)?, что вопрос в том, что виртуальная машина видит мой новый объект [емкость] как массив объектов. Я согласен с этой точкой, но это было, когда определение для моего AbstractArrayMyList было еще

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

, а это означает, что усилитель должен рассматривать Е как на объект, так как он ничего не знает еще об этом. но так как Я добавил, что E extends Comparable не должен допускать, чтобы этот листинг был разрешен? JVM распознает это как массив сопоставимых объектов ектов?

ответ

0

Проблема заключается в том, что объект не сопоставим. Таким образом, создание массива терпит неудачу в конструкторе абстрактного класса.

Вы можете решить эту проблему путем удаления Comparable части в абстрактной декларации:

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

} 

И тогда в вашем подклассе:

public class ArrayListSorted<E extends Comparable<E>> extends AbstractArrayMyList<E> { 
    ... 
} 

делает все работы. Исключение исключений класса.

В любом случае это будет лучше, так как прежде, чем вы ограничили бы все подклассы AbstractArrayMyList для сравнения. Теперь этого не должно быть.

UPDATE

теперь я понимаю, что вы будете прибегать элементы в абстрактном классе.В этом случае, сделайте ваш массив типа Сравнительное:

public abstract class AbstractArrayMyList<E extends Comparable<E>> implements List<E> { 

    ... 

    public AbstractArrayMyList(int capacity) { 
     elementData = (E[]) new Comparable[capacity]; 
    } 

    ... 

Тогда все ваши сортировкой будет работать:

К примеру, имеющий основной метод этого:

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 

(это предполагает, что ваша надстройку() код в вашем абстрактных курортах класса массив)

UPDATE 2

Если сортировка в дочернем классе, то вам придется сделать несколько незначительных изменения в абстрактном класс.

Самый простой способ сделать эту работу для абстрактного класса, чтобы получить массив, переданный через конструктор. Таким образом, дочерние классы образуют тип массива.

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

... 

Теперь код снова работает, как это должно

+0

Я тоже это пробовал, но проблема в том, что AbstractArrayMyList работает с массивом elementData, который содержит элементы, которые не обязательно являются сопоставимыми, потому что E не реализует Comparable в AbstractArrayMyList – committedandroider

+0

О, я вижу, я обновлю свой ответ – dkatzel

+0

спасибо :))) И неважно, чтобы несортированный массив работал с типами Comparable? – committedandroider

0

Если J позволила, что вы можете поместить объект, кроме Е, скажет строки, и при извлечении объекта вы предполагаете, что это будут Е и приведение его в Е, что приведет к ClassCastException во время выполнения. Генераторы точно предотвращают это, обнаруживают как можно больше сбоев во время компиляции.

+0

Так Integer кладется как E, а затем, когда она будет извлечена, она не может быть брошен обратно? – committedandroider

+0

@committedandroider, если JVM разрешил то, что вы сделали, ДА. – Pandiri

+0

Но E может быть любым типом объекта, хотя String – committedandroider

Смежные вопросы