以下代码片段有一个奇怪的行为。任何人都可以详细解释
下面的代码抛出了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{}
您注意到的行为与继承的基本规则有关。
对于第一个片段,你将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
。编译器不等待它在运行时失败,因为它可能使编译立即失败,这是更好的。