【问题标题】:Assigning a char array to an int array将 char 数组分配给 int 数组
【发布时间】:2011-08-08 16:30:22
【问题描述】:

谁能解释一下为什么下面代码中的最后一个赋值无效

ScjpTest 类扩展 BounceObject 实现 Bouncable{

static int ac = 5;
static char ab = 'd';

static int[] a = new int[]{1,2,3};
static int[] b = new int[]{1,2,3};
static char[] c = new char[]{'a','b'};

public static void main(String[] args){  
    a = b;
    b = a;

    ac = ab;  //This is accepted
    a = c;    //This is rejected
}

}

编译器报错如下

ScjpTest.java:10: incompatible types
found   : char[]
required: int[]
                a = c;
                    ^
1 error

以下也接受

class Animal{}
class Horse extends Animal{]

Animal[] animals = new Animal[2];
Horse[] horses = new Horses[2];

animals = horses;

为什么我不能将 char 数组分配给 int 数组?

【问题讨论】:

  • 我假设您希望 class Horse extends Animal{} 用于您的示例

标签: java arrays


【解决方案1】:

因为语言规范禁止这样做。它在运行时将 String[] 视为 Object[],因为它们在内存中具有相同的表示形式。但是 char[] 和 int[] 有不同的内存表示,如果对 int[] 的每个操作都必须检查它是否真的是伪装的 char[],那将是不可接受的慢。

引用类型的数组确实必须对 assignments 进行运行时检查,以便知道是否抛出 ArrayStoreException,但至少从它们中读取是独立于元素类型的。

【讨论】:

  • 谢谢。我现在明白他们为什么决定限制它了:)
【解决方案2】:

数组本身就是一个类型,并且转换的工作方式与它的基元不同。所以你必须循环所有元素并将它们分配给另一个数组的相应元素。

【讨论】:

    【解决方案3】:

    您可以将 char 变量分配给 int 变量,因为编译器应用了扩展转换。基础是 int 比 char 大,因此在转换中不会丢失信息。如果您尝试将您的 int 分配给您的 char,您会注意到编译器会拒绝您的代码,直到您输入特定的类型转换。这是因为缩小转换几乎总是涉及数据丢失,因此编译器要求您(程序员)明确指出这是您打算做的事情。

    同样的原则也适用于对象。隐式允许扩大转换,缩小转换需要类型转换。请注意,您在任何时候都不能转换不通过超类/子类层次相互关联的对象。

    Number n = null;
    Integer i = null;
    
    n = i ;         // Allowed without casting, Number is superclass of Integer
    i = n;          // Compiler error, Integer is sub-class of Number
    i= (Integer)n;  // Allowed due to the type-cast
    

    在上面的例子中,Number 是 Integer 的超类。在没有类型转换的情况下允许将 Integer 的实例分配给 Number 的实例,因为这是一种“扩展”转换。将 Number 的实例分配给 Integer 的实例需要特定的转换,因为这是一种缩小转换(Number 可以表示 Float 或其他一些子类)。这些规则延续到数组。因此,您可以执行以下操作:

    Number[] numArr = null;
    Integer[] intArr = null;
    
    numArr = intArr;
    intArr = numArr;              //Compile error
    intArr = (Integer[]) numArr;
    

    对于原始数组,没有对数组元素进行扩展转换,即使在您认为它可能有意义的情况下(例如,从 char 到 int,或字节到字符等)。虽然这似乎没有意义,但如果您查看对象类似物,就会更清楚为什么:

    Double[] doubleArr = null;
    Integer[] intArr = null;
    
    doubleArr = intArr ;      // Compile error, Double,Integer are sibling classes
    doubleArr = (Double[]) intArr;  // Compile error, same reason
    intArr = doubleArr;             // Compile error, same reason
    intArr = (Integer[]) doubleArr; // Compile error, same reason
    

    您不能将 Double 转换为 Integer,反之亦然,从编译器的角度来看,它们是完全不同的类(例如,String 和 Float 就不同)。

    【讨论】:

      猜你喜欢
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-04
      • 2019-05-18
      • 2018-10-06
      • 2013-12-18
      相关资源
      最近更新 更多