1

有人可以解释一下这个程序是如何执行的吗?

这是我似乎无法得到它的输出的代码:

    class Box {
        int size;
        Box (int s) {
           size = s;
        }
    }
    public class Laser {
        public static void main(String[] args) {
            Box b1 = new Box(5);
            Box[] ba = go(b1, new Box(6));
            ba[0] = b1;
            for(Box b : ba)
                System.out.println(b.size + " ");
        }

        static Box[] go (Box b1, Box b2) {
            b1.size = 4;
            Box[] ma = {b2, b1};
            return ma;
        }
    }

我运行它时的实际输出是 4, 4。但根据我的理解,这应该是 5, 4。任何人都可以帮助理解这是如何执行的吗?

4

7 回答 7

3

我已经为你添加了评论;

The important TWIST that you missed here is;

Box[] ma = {b2, b1};它不是{b1,b2}。返回时交换内存位置。

       public static void main(String[] args) {
            Box b1 = new Box(5);                 // b1 == location A
            Box[] ba = go(b1, new Box(6));       // ba == location B which stores Location A, D

           // PLEASE NOTE HERE
           // After the function go() is executed;
           // ba[] will have {D, A}
           // So ba[0] will have object b1 which is at location A. 

            ba[0] = b1;                          // location B will now store A and A
            for(Box b : ba)
                System.out.println(b.size + " ");  //  Output: 4 and 4
        } 

        static Box[] go (Box b1, Box b2) {        // go(location A, location D )
            b1.size = 4;                          // A's object.size = 4
            Box[] ma = {b2, b1};                  // position is interchanged here (D and A)
            return ma;                            // return the location of ma
        }

希望这可以帮助。

如果您有任何问题,请告诉我。在java中,一切都是按值传递的。内存地址按值传递。

于 2013-08-13T15:38:13.037 回答
0

传递给的值go是对对象的引用。如果您来自 C,您可以将参数视为具有指针类型,例如

Box** go (Box *b1, Box *b2) {
     b1->size = 4;
     /* allocate an array of Box*, set it up, return it */
}

(对不起,如果我弄错了 C 语法。)指针(引用)本身是按值传递的,这意味着如果你在“go”(在 C 程序中)说:

b1 = &some_other_box;

它不会影响调用端的任何变量,并且在 Java 中的工作方式相同。这使它与varPHP 或 Pascal 中的参数有点不同。

于 2013-08-13T15:38:21.860 回答
0

当您将对象作为参数传递时,您实际上是在传递对它的引用的副本。也就是说,如果您在方法内修改参数对象,则该对象将在该方法返回时保留这些修改,这就是您看到在返回后b1保留size = 4分配的原因go

于 2013-08-13T15:34:24.370 回答
0

Java 在方法调用中传递对对象的引用副本。

您不能通过分配对象来更改它。

public static void main(String[] args) {
    Box b1 = new Box(5);
    Change(b1);
    System.out.println(b1.size + " ");

static void Change(Box b1) {
    b1 = new Box(6);
}

这将始终返回 5,因为该函数Change仅将副本覆盖到引用的对象。

但是,您可以像这样影响对象的属性:

public static void main(String[] args) {
    Box b1 = new Box(5);
    Change(b1);
    System.out.println(b1.size + " ");

static void Change(Box b1) {
    b1.size = 6;
}

这将返回 6(对对象的引用保持不变)。

于 2013-08-13T15:52:56.027 回答
0

Java 总是在方法调用中传递对对象的引用。当您调用go时,第一个参数 ( b1) 是对b1 Box您在main. 然后,您修改该对象,其size为 now 4

于 2013-08-13T15:35:39.023 回答
0

如果原始帖子中的函数“go”在 C 中(并且 b1 和 b2 是 C 指针),它可以做以下两件事(调用者会看到):

  1. 更改 b1 和 b2 指向的数据结构中的变量值。
  2. 使原来的 b1 和 b2 指向不同的数据结构。

在 Java 中,我们可以做 1 但不能做 2,因为 go 无法访问原始的 b1 和 b2。(它可以访问 b1 和 b2 的副本。在子程序开始时,副本 b1 指向与原始 b1 相同的对象,依此类推。)

说Java是通过调用传递确实错过了一些东西,即函数做1的能力,即改变b1和b2引用的堆中对象的属性。[这就是语句中发生的事情,b1.size = 4;,这导致了原始发布者的混乱。]

“go”中的 b1 与“main”中的 b1 位置不同。但是,当函数启动时,'go' 中的 b1 引用与 'main' 中的 b1 相同的对象,并且当使用 'main' 中的 b1 作为引用时,将看到使用 'go' 中的 b1 对对象所做的任何更改。

但是,如果 'go' 中的 b1 设置为另一个 Box,则 'main' 中的 b1 将不会看到这个;它仍然会看到以前的 Box。

于 2013-12-28T11:35:31.940 回答
-1

在 Java 中,对象通过引用传递,基元通过值传递。

public class Laser {
    public static void main(String[] args) {
        //Create a Box of size 5.
        Box b1 = new Box(5);
        //Create an array of Box objects, which are the results of the go method
        Box[] ba = go(b1, new Box(6));
        // ba now looks like {new Box(6), b1 /*b1 is size 4 now*/}
        // assign reference to b1 at index 0 in ba.
        ba[0] = b1;
        // array now looks like {b1, b1}
        for(Box b : ba)
            System.out.println(b.size + " ");
    }

    static Box[] go (Box b1, Box b2) {
        //set the size of the first box to 4
        b1.size = 4;
        //create an array of boxes, with b2 in index 0 and b1 in index 1
        Box[] ma = {b2, b1};
        return ma;
    }
}
于 2013-08-13T15:34:07.440 回答