java 中以奇怪的方式出现 ClassCastException 和编译问题
ClassCastException and compilation issue in strange manner in java
下面的代码片段有一个奇怪的地方behaviour.can谁能详细解释一下
下面的代码抛出 ClassCastException 但 inks.get(0) 给出了无法转换为 BlackInk 的 ColorInk,因为没有 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{}
下面的代码又很奇怪,当只有 Arraylist 泛型是 ColorInk 时,它编译失败而不是 ClassCastException没有 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
。编译器不会等待它在运行时失败,因为它可能使编译立即失败,这样更好。
下面的代码片段有一个奇怪的地方behaviour.can谁能详细解释一下
下面的代码抛出 ClassCastException 但 inks.get(0) 给出了无法转换为 BlackInk 的 ColorInk,因为没有 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{}
下面的代码又很奇怪,当只有 Arraylist 泛型是 ColorInk 时,它编译失败而不是 ClassCastException没有 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
。编译器不会等待它在运行时失败,因为它可能使编译立即失败,这样更好。