ClassCastException и проблема компиляции странным образом в Java - PullRequest
0 голосов
/ 08 сентября 2018

Приведенные ниже фрагменты кода имеют странное поведение. Кто-нибудь может объяснить подробно, пожалуйста

В приведенном ниже коде выбрасывается ClassCastException, но inks.get (0) дает ColorInk, который не может быть преобразован в BlackInk, поскольку нет отношения IS-A. Затем следует указать ошибку компилятора, почему он успешно компилируется и вызывает исключение ClassCastException.

    import java.util.ArrayList;
    public class ListAccess {
      public static void main(String[] a){
        ArrayList<Ink> inks=new ArrayList<Ink>();
     inks.add(new ColorInk());
     inks.add(new BlackInk());
     Ink ink=(BlackInk) inks.get(0);
  }
}

class Ink{}
class ColorInk extends Ink{}
class BlackInk extends Ink{}

Приведенный ниже код снова странный: он не выполняет компиляцию вместо ClassCastException, когда только Arraylist generic является ColorInk, что делает разницу в обоих случаях list.get (0) возвращает ColorInk, который преобразуется в BlackInk, где нет IS-A отношения.

import java.util.ArrayList;
        public class ListAccess {
          public static void main(String[] a){
            ArrayList<ColorInk> inks=new ArrayList<Ink>();
         inks.add(new ColorInk());
         Ink ink=(BlackInk) inks.get(0);
      }
    }

class Ink{}
class ColorInk extends Ink{}
class BlackInk extends Ink{}

1 Ответ

0 голосов
/ 08 сентября 2018

Поведение, которое вы заметили, связано с основными правилами наследования.

Для первого фрагмента вы понижаете значение Ink до BlackInk:

Ink ink=(BlackInk) inks.get(0);

Компилятор принимает его как Ink может быть BlackInk. Но принижение может все же произойти, если приведение недействительно во время выполнения. Вот что происходит, когда inks.get(0) обозначает ColorInk.

Во втором фрагменте:

ArrayList<ColorInk> inks=new ArrayList<Ink>();
...
Ink ink=(BlackInk) inks.get(0);

компилятор останавливает вас, потому что вы хотите привести объект с объявленным типом к типу, который не может быть совместимым: ColorInk не может быть BlackInk в соответствии с определенной вами иерархией. Компилятор не ждет, что он выйдет из строя во время выполнения, поскольку это может привести к сбою компиляции прямо сейчас, что лучше.

...