今天我编写了关于声明数组语法的简单测试,因此,有3个类:
public class A {
}
public class B extends A {
}
public class C extends A {
}
我尝试使用下一个语法
创建数组A[] aa = new B[10];
所以,有可能,但是我们可以只向这个数组添加类B
的实例,如果您尝试添加A
或C
的实例,则会收到{{3}问题,为什么我们可以使用这样的语法创建数组,它可以在哪里使用并获得一些利润?
感谢。
答案 0 :(得分:4)
数组包含类型Bs。即使引用aa可以包含A [],B []或C []类型的数组,(因为C和B都扩展了A),在运行时,数组只能保存Bs。
A类不是B.C类不是B.因此是运行时异常。
编辑:
这样的代码有很多潜在的用途。例如,您可以声明这样的数组,因为您可能直到运行时才知道您正在使用的更明确的类型。
例如:
Animal[] animals;
if (useDogs) {
animals = new Dog[num];
} else {
animals = new Cat[num];
}
loadIntoCar(animals);
答案 1 :(得分:3)
在语言中允许使用此语法的原因是,有时您不关心数组中的对象的子类。数组子类型的Java Language Specification rules包括:
如果 S 和 T 都是参考类型,那么 S [] > 1 T [] iff S > 1 T 。
(其中> 1 表示“直接子类型”)。
这允许人们编写这样的方法:
public void printArray(Object[] array) {
System.out.print('[');
boolean first = true;
for (Object obj : array) {
if (!first) {
System.out.print(", ");
} else {
first = false;
}
System.out.print(String.valueOf(obj));
}
System.out.print(']');
}
然后用:
调用它String[] foo = { "a", "b", "c" };
printArray(foo);
此语言功能确实会导致将ArrayStoreException问题延迟到运行时的不幸影响。
答案 2 :(得分:0)
数组类型为covariant,这意味着您可以声明A [] a = new B [](相反,收集不是:您不能声明List< A> a = new List< B> ())。
这就是为什么编译器不能先发制人地检查你是否只在数组中放入有效类型的元素,这就解释了为什么只有在运行时,当你试图将一个元素插入到数组中时,检查才会发生。
答案 3 :(得分:0)
如果您需要示例,请查看Arrays。如果Java不允许数组多态,我们就无法使用sort(Object[] a)
,toString(Object[] a)
,binarySearch(Object[] a, Object key)
等功能。请记住B
和C
是Object
的子类型,因此您可以将这些功能用于所有这些。请注意,数组早于泛型(Java 1.5.0),甚至泛型都有它的缺陷(Java的折衷是因为类型擦除而无法在运行时知道泛型类型)。