Java 将char数组分配给int数组
有人能解释一下为什么下面代码中的最后一个赋值无效吗 类ScjpTest扩展BounceObject实现可反弹{Java 将char数组分配给int数组,java,arrays,Java,Arrays,有人能解释一下为什么下面代码中的最后一个赋值无效吗 类ScjpTest扩展BounceObject实现可反弹{ 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){
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;
那么为什么我不能将字符数组分配给int数组呢?数组本身就是一种类型,强制转换的工作方式与它的原语不同。因此,您必须循环所有元素并将它们分配给另一个数组的相应元素。数组本身就是一个类型,强制转换的工作方式与它的原语不同。因此,必须循环所有元素并将它们分配给另一个数组的相应元素。因为语言规范禁止这样做。它在运行时将字符串[]作为对象[]查看,因为两者在内存中具有相同的表示形式。但是char[]和int[]有不同的内存表示形式,如果int[]上的每个操作都必须检查它是否真的是伪装的char[],那么它的速度会慢得令人无法接受
引用类型的数组确实必须对赋值进行运行时检查,以便知道是否抛出ArrayStoreException,但至少从它们读取的内容与元素类型无关。,因为语言规范禁止这样做。它在运行时将字符串[]作为对象[]查看,因为两者在内存中具有相同的表示形式。但是char[]和int[]有不同的内存表示形式,如果int[]上的每个操作都必须检查它是否真的是伪装的char[],那么它的速度会慢得令人无法接受
引用类型的数组确实必须对赋值进行运行时检查,以便知道是否抛出ArrayStoreException,但至少从这些数组中读取的内容与元素类型无关。您可以将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[] numArr = null;
Integer[] intArr = null;
numArr = intArr;
intArr = numArr; //Compile error
intArr = (Integer[]) numArr;
对于基本数组,即使在您认为可能有意义的情况下(即字符到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强制转换为整数,反之亦然,从编译器的角度来看,它们是完全不同的类,例如,与String和Float完全不同。您可以将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[] numArr = null;
Integer[] intArr = null;
numArr = intArr;
intArr = numArr; //Compile error
intArr = (Integer[]) numArr;
对于基元数组,即使在您认为可能有意义的情况下(即字符到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转换为整数,反之亦然,从编译器的角度来看,它们是完全不同的类,就像字符串和Float一样不同。我假设您希望类Horse扩展Animal{}作为示例我假设您希望类Horse扩展Animal{}作为示例谢谢。我现在明白他们为什么决定限制它了:谢谢。我现在明白他们为什么决定限制它了: