Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么输出会是';100';和';500';?_Java - Fatal编程技术网

Java 为什么输出会是';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

我不明白为什么下面程序的输出打印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; 
        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]);