假设我们有以下程序:
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class Main {
public static void main(String[] args) {
Fruit[] fruit = new Apple[10];
try {
fruit[0] = new Fruit(); // ArrayStoreException
fruit[0] = new Orange(); // ArrayStoreException
} catch(Exception e) { System.out.println(e); }
}
}
基于Java documentation:
抛出以表示已尝试存储错误的内容
将对象类型转换为对象数组。
我读过here
创建数组时,它会记住要存储的数据类型。
如果数组记住了它包含的数据类型,则意味着它知道它包含的数据类型。但是我发布的代码段已正确编译,因此在编译时,数组显然不知道所包含的类型。
我的问题是:
ArrayStoreException
? ArrayStoreException
吗? 最佳答案
创建数组时,它会记住它意味着什么类型的数据
商店。
数组仅“记住”在运行时它实际包含的类型。
首先声明数组,在这种情况下,声明为Fruit数组。
然后创建数组,在本例中为Apple数组。
创建是在运行时期间进行的,但是编译器仅设计用于验证仅向数组分配了声明为其类型的对象。在运行期间可能发生很多事情。
考虑以下代码:
class Fruit {}
class Apple extends Fruit {}
class Jonathan extends Apple {}
class Orange extends Fruit {}
public class Main {
public static void main(String[] args) {
Fruit[] fruit = new Apple[10];
boolean alt = (Math.random() < 0.5);
try {
fruit[0] = fruitFactory(alt);
} catch(Exception e) { System.out.println(e); }
}
private static Fruit fruitFactory(boolean apple) {
if (apple) {
return new Apple();
} else {
return new Orange();
}
}
}
该代码与您的代码相同,只不过通过fruitFactory方法为fruit [0]分配了一个值。编译器无法判断布尔alt是
true
还是false
。编译器缺少哪些信息才能意识到这一点
分配是不可能的吗?
如前所述-编译器无法判断分配是否可行。
有没有这样的代码是正确的,所以没有
引发ArrayStoreException吗?
是的,在上面的代码中有50%的情况。您要么必须验证分配的对象与数组相同,要么捕获异常。