我可以按如下方式将char赋值给int。
char c = 'a';
int a = 0;
a = c;
那么,为什么我不能将 char []分配给int [] ?
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars; // Cannot convert from char[] to int[] ?? But why?
答案 0 :(得分:4)
char
到int
促销is a special provision for primitive types.
关于数组,Java Language Specification says this:
如果数组变量v具有类型A [],则其中A是引用类型,则 v可以保存对任何数组类型B []的实例的引用 B可以分配给A.这可能会导致a上的运行时异常 后来的任务;有关讨论,请参见§10.10。
这仅适用于“如果A是引用类型。”即使char
可以分配给int
,此规则也不适用,因为它不适用适用于原始类型。
因此,在没有任何特殊规定来分配不兼容类型的情况下,分配失败。
如果允许的话,你会引入ArrayStoreException
在存储上引发到原始数组的可能性(就像你目前使用引用类型数组一样):
ints[0] = Integer.MAX_VALUE; /* Exception! */
这是因为ints
是char[]
的别名,无法容纳32位值。我不确定为什么这对于引用类型是可接受的,而不是对于原语,但它可能与原语所需的所有特殊处理有关。
答案 1 :(得分:2)
除了在语言规范中不存在从char []到int []的转换概念之外,我不确定能为您提供更多。
在较低级别,它可能与通过数组本身的迭代有关。如果我将一个char []视为int [],那么通过它在内存中以低级别进行索引将不起作用。一个4字节的步骤(像int []一样处理)实际上会在char []中执行2个索引。
答案 2 :(得分:2)
然后,为什么我不能将char []分配给int []?
第一个答案是因为Java语言规范禁止这样做。关键部分是4.10.3.,它指定了数组类型的子类型规则。规则意味着没有原始数组类型是另一个(不同的)原始数组类型的子类型。其中一个后果是禁止转让。
第二个答案(以及JLS禁止它的原因)是,如果允许,它会破坏类型系统。考虑这个例子:
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars;
作业是参考作业。这意味着ints
现在将指向由前一行new char[4]
创建的数组对象。 (它不等同于将chars
'元素的值赋给ints
的循环。)
现在让我们添加一个方法:
public void paranoidIncrement(int[] ints) {
for (int i = 0; i < ints.length; i++) {
int tmp = int[i];
ints[i] = ints[i] + 1;
assert tmp + 1 == ints[i];
}
}
让我们将它与之前的代码结合起来:
int[] ints= new int[4];
char[] chars= new char[4];
ints = chars; // assume this is legal ...
paranoidIncrement(ints);
那是什么意思?好的paranoidIncrement
会将参数(实际上是char[]
)视为int[]
。但是当我们ints[i] = ints[i] + 1;
时会发生什么?如果实际数组的单元格确实是char
s,则JVM 具有来截断值以使它们适合,或抛出异常。
如果它截断该值,则assert
语句将失败。这是违反直觉的,它只是简单的破碎。
如果它抛出一个异常,那么我们突然得到了一大堆在编译时检测到的(在JLS规则下)的新bug。
Java避免破坏的方式是说无法将char[]
分配给int[]
。
答案 3 :(得分:1)
int[] a = new int[4];
int[] b = a;
a
和b
都会引用同一个数组 - 不涉及复制。
如果允许ints=chars
,则会有int[]
变量引用16位char
的数组。诸如ints[0] = 0x12345678
之类的作业是有效的,但结果应该是什么?
答案 4 :(得分:0)
您无法以这种方式分配,因为它是类型不匹配。 int []和char []类型不兼容。
答案 5 :(得分:0)
它无法正常工作,因为(在第一种情况下)语言隐藏了一些类型转换详细信息。也就是说,当您将char
分配给int
时,有时会将其称为隐式广告。这相当于这样做:
char c = 'a';
int a = 0;
a = (int) c;
...哪种方法可以正常使用,但语言不会强迫你每次都写(int)
演员。
在第二个示例中,强制转换不起作用。如果您尝试添加显式强制转换,则会出现错误,例如:
Foo.java:9: inconvertible types
found : char[]
required: int[]
int[] ints = (int[]) chars;