Java 为什么输出会是';100';和';500';?
我不明白为什么下面程序的输出打印100和500? 有人能解释这是怎么发生的吗Java 为什么输出会是';100';和';500';?,java,Java,我不明白为什么下面程序的输出打印100和500? 有人能解释这是怎么发生的吗 public class ArraysInJava { public static void main(String[] args) { int[] a = new int[3]; a[1] = 50; Object o = a; int[] b = (int[])o; b[1] = 100; Sy
public class ArraysInJava
{
public static void main(String[] args)
{
int[] a = new int[3];
a[1] = 50;
Object o = a;
int[] b = (int[])o;
b[1] = 100;
System.out.println(a[1]);
((int[])o)[1] = 500;
System.out.println(a[1]);
}
}
实际上,您正在引用相同的内存地址(指针),因此当您更改值时,内存地址中的内容也会更改 让我们一行一行地做这个
public class ArraysInJava
{
public static void main(String[] args)
{
int[] a = new int[3]; // a = {0, 0, 0} as default value for int elements is 0
a[1] = 50; // a = {0, 50, 0}
Object o = a; // o = a = {0, 50, 0} - casting affects the variable type, the referenced object remains the same (recall that objects are saved by reference)
int[] b = (int[])o; // b = o = a = {0, 50, 0}
b[1] = 100; // b = o = a = {0, 100, 0}
System.out.println(a[1]); // Prints 100
((int[])o)[1] = 500; // b = o = a = {0, 500, 0}
System.out.println(a[1]); // Prints 500
}
}
所有的强制转换都不会做任何事情,因为它只会影响您在编译时可以对其执行的操作。例如,您不能编写o[1]
,因为它在编译时不是数组
编辑
在评论中确实提出了一个重要的观点。我认为缺少的部分是关于数据类型的
主要有两种数据类型:基本数据类型和非基本数据类型
基本数据类型包括字节
,短
,长
,浮点
,双
,字符
,布尔
。当您将这些数据类型的变量传递到方法中或分配给另一个变量时,您就是在传递值
非基本数据类型(您可以称之为对象类型)是上述所有类型之外的所有其他类型。这包括数组(也包括基元类型的数组)、枚举、类、接口和String
当您将这些数据类型的变量传递到方法中,或将它们分配给另一个变量时,您传递的是对象的引用
int[] a = {1, 2};
Object b = a; // "b" now holds the reference (memory address) of the "a"
int[] c = b; // "c" now also points to the exact same array
b = null; // "b" holds no memory reference now, "a" and "c" continues to hold reference of the same array
基本上,变量
o
、b
、a
都是对同一数组的引用。
因此,无论使用哪种引用来修改数组的第二个元素,数组的第一个元素都将发生更改
首先,使用a[1]=50将其更改为50
然后使用b[1]=100将其更改为100
然后使用(int[]o)[1]=500将其更改为500
如果调试代码,可以找到以下操作:
首先,a=[0,0,0]
a=[0,50,0]
o=[0,50,0]
b=[0,50,0]
b=[0100,0]->o=[0100,0]->a=[0100,0]
打印a[1]=100
o[1]=500->o=[0500,0]->b=[0500,0]->a=[0500,0]
打印a[1]=500
这就是[1]的值的更改方式
基本上,同一个数组a一直在变化。绘制内存模型并跟踪每个引用,如果您理解这一点,请参阅代码中的注释,这将消除您的混淆<代码>a、b和o是参考
a[1]------> 50
a[1]------> 50 <------------o[1]
a[1], b[1]------->50 <---------------o[1]
a[1], b[1] -------->100 <-----------o[1] (but the value 50 is overwritten with 100)
a[1], b[1] -------->500<-----------o[1] (but the value 100 is overwritten with 500)
a[1]------>50
a[1]--->50 50 100 500 50,
对象o=a;//在这里,您创建了一个数组对象a
,并在位置1处以50初始化。
对象o
是a
的参考变量,这意味着两者都持有保存值和位置。之后,您创建了另一个o
的参考变量b
,这里b
是o
的参考变量,o
是a
的参考变量,因此b也是a
的参考变量。
如果试图通过任何引用变量更新值,则所有引用将保持相同的值(意味着所有引用的值都将更改)。在本例中,您正在执行相同的操作
参考变量b
,-->第9行更新的a
在1处的值
由参考变量o
更新的a
在1处的值-->第11行数组是java中的一个对象。当对对象使用“=”赋值运算符时,它实际上指向内存中的同一个对象,而不会创建新对象。像
int[] a = new int[3];
a[1] = 50;
Object o = a; // now o and a will point to same object in memory
//Any changes done in either a or o will reflect in both
int[] b = (int[])o; // now a,b and o pointing to same array in memory
b[1] = 100;
System.out.println(a[1]);
((int[])o)[1] = 500;
System.out.println(a[1]);
所以内存中只有一个数组;a、 b和o指向同一个数组,因此使用引用变量a、b或o对数组所做的任何更改都将在同一个数组中执行。您希望它打印什么?为什么?为什么不是100和500?@S.K.因为您已将500
指定给数组的第一个元素-您从未实际更改过任何对象使用的内存引用,您只是让它们彼此指向对方,因为您只创建了Integer Array的一个对象,并且在前面提到的步骤中更改了索引1
的值。因此,即使您将int[]类型转换为object
和object类型转换为int[]
创建对象的引用也将保持不变。希望这会有所帮助:)这对数组的第二个元素也是有效的,它实际上正在被更改…哦,糟糕,这就是我的意思。更新了我的答案重要的不是施法,而是=
不复制数组,数组是一个对象(与原语不同)@CarlosHeuberger是的,当我再次阅读时,我认为重要的一点确实是关于知道对象是引用类型。@Sreejith G这是一个实际的演示,它将详细阐述我的评论:)有点混乱,没有解释为什么b
的值转到o
而不是c
。主要的一点是它们都是相同的对象(b==o==a
左右)是的,因为它们都是相同的,我没有提到这一点
int[] a = new int[3];
a[1] = 50; // a------> 50,
Object o = a; // a------> 50 <------------o
int[] b = (int[])o; // a, b------->50 <---------------o
b[1] = 100; //a, b -------->100 <-----------o(but the value 50 is overwritten with 100)
System.out.println(a[1]); // so prints 100
((int[])o)[1] = 500; //a, b -------->500<-----------o(but the value 100 is overwritten with 500)
System.out.println(a[1]); // hence prints 500
int[] a = new int[3];
a[1] = 50;
Object o = a; // now o and a will point to same object in memory
//Any changes done in either a or o will reflect in both
int[] b = (int[])o; // now a,b and o pointing to same array in memory
b[1] = 100;
System.out.println(a[1]);
((int[])o)[1] = 500;
System.out.println(a[1]);