以下代码段的行为很奇怪。任何人都可以详细解释
下面的代码引发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{}
答案 0 :(得分: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
。编译器不会等待它在运行时失败,因为它可能使编译立即失败,这更好。