byte b =10;
int a = b; // Primitive data type widening
// Works perfectly fine
上面的代码不会给出任何错误/警告。但为什么同样不适用于下面提到的代码?
byte[] b = new byte[10];
int[] i1 = b; //Cannot convert from byte[] to int[]
int[] i2 = new byte[10]; //Cannot convert from byte[] to int[]
我的问题是,因为int可以保存任何和所有字节值,为什么数组不是这种情况呢?
他们都在拿着地址。如果这对于ref变量是可能的话,这将是 upcasting 。答案 0 :(得分:8)
new byte[10]
创建的数组可以包含10个byte
值。如果您能够将其分配给int[]
类型的变量,编译器将(错误地)假设您的byte
数组可以包含10个int
值。
请考虑以下代码,该代码无效:
byte[] b = new byte[10];
b[0] = 10000; // too large for byte
以及以下有效的代码:
int[] i2 = new int[10];
i2[0] = 10000;
如果int[] i2 = new byte[10];
有效,编译器会允许您将int
存储在byte
类型的变量中。
答案 1 :(得分:5)
语言规范定义Sec 4.10.3中数组类型之间的子类型:
以下规则定义了数组之间的直接超类型关系 类型:
如果
S
和T
都是参考类型,那么S[] >1 T[] iff S >1 T
。
Object >1 Object[]
Cloneable >1 Object[]
java.io.Serializable >1 Object[]
如果
P
是基本类型,则:
Object >1 P[]
Cloneable >1 P[]
java.io.Serializable >1 P[]
最终的项目符号(“如果P
是基本类型......”)表明该语言没有定义不同基元类型的数组之间的任何关系。唯一有效的作业是:
byte[] bs = new byte[10];
byte[] bs2 = bs;
Object obj = bs;
Cloneable cl = bs;
Serializable ser = bs;
这并没有提供为什么这样的答案;你必须问语言设计师。然而,像Eran所示的简单示例证明了为什么OP提出的做法不安全。
应该注意的是第一行 - 它允许像
那样的赋值Object[] obj = new String[10];
obj[0] = new Object(); // ArrayStoreException!
是一个设计错误:数组是协变的,因此它们不是类型安全的。这是强烈偏好泛型到数组的一个原因,因为泛型是不变的,因此阻止了这样的赋值。