无法从char []转换为int []

时间:2012-01-26 00:50:49

标签: java

我可以按如下方式将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?

6 个答案:

答案 0 :(得分:4)

charint促销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! */

这是因为intschar[]的别名,无法容纳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;

ab都会引用同一个数组 - 不涉及复制。

如果允许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;