在Java中以奇怪的方式出现ClassCastException和编译问题

问题描述 投票:0回答:1

以下代码片段有一个奇怪的行为。任何人都可以详细解释

下面的代码抛出了ClassCastException,但是inks.get(0)给出了ColorInk,由于没有IS-A关系,因此无法将其转换为BlackInk。然后应该给出编译器错误,为什么它成功编译并抛出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{}

下面的代码再次奇怪的是,当只有Arraylist泛型是ColorInk时,它无法编译而不是ClassCastException。在两种情况下,list.get(0)返回的ColorInk将被转换为没有IS-A关系的BlackInk。

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{}
java classcastexception
1个回答
1
投票

您注意到的行为与继承的基本规则有关。

对于第一个片段,你将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。编译器不等待它在运行时失败,因为它可能使编译立即失败,这是更好的。

© www.soinside.com 2019 - 2024. All rights reserved.