如果 Java 是一种 "call-by-value" 语言那么为什么会这样?

If Java is a "call-by-value" language then why is this happening?

查看测试代码:

class Node
{
    int num = 0;
}

class TestPassByReference
{
    void increaseByOne(Node N)
    {
        N.num++ ;
    }

    public static void main(String args[])
    {
        Node N = new Node() ;
        TestPassByReference T  = new TestPassByReference() ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
    }
}

给出结果:

num = 1
num = 2
num = 3

这里的问题是,既然 Javacall by value 那么 Nodenum 属性应该保持为 0。

我认为这是由于创建了一个对象 T,该对象本应包含一个对象 N。但是T里面没有属性可以保存一个Node类的对象。那么这是怎么发生的呢?

非常感谢任何帮助。

月亮。

Java 通过引用传递对象。 Node N 是一个对象。因此,当您执行 N.num++ 时,您正在递增同一对象的整数。

在您的代码中,您有 class 节点的单个对象。

保存 num 的初始值为 0 的值, 当调用函数和增加 num 的值时,每次 num 的值都会增加,因为相同的节点 class 对象。其简单易懂的节点对象是 class 节点的实例,如果您创建另一个节点 class 对象,它将是 class 的不同实例。

class Node
{
    int num = 0;
}
class TestPassByReference
{
    void increaseByOne(Node N)
    {
        N.num++ ;
    }
    public static void main(String args[])
    {
        Node N1 = new Node() ;
        Node N2 = new Node() ;
        TestPassByReference T  = new TestPassByReference() ;
        T.increaseByOne(N1) ;
        System.out.println("num = "+N1.num) ;
        T.increaseByOne(N1) ;
        System.out.println("num = "+N1.num) ;
        T.increaseByOne(N2) ;
        System.out.println("num = "+N2.num) ;
    }
}

结果是:

num = 1
num = 2
num = 1

好吧,您正在创建 Node 和 TestPassByReference 的单个对象,因此 T 引用了您之前在云中创建的相同 Node 引用。因此,当您调用该方法时,相同的值会增加。

Java 是按值调用,因为 references 是按值传递。

这意味着您可以更改传递给 N 的对象的内部状态(例如,通过修改 num 字段的值)但您不能将 N 重新分配给新对象 (例如 N = null;N = new Node();).

class Node
{
    int num = 0;
}

class TestPassByReference
{
    void increaseByOne(Node N)
    {
        N.num++ ;
        System.out.println("num value is:" + N.num);
    }

    void increaseByOneThenChange(Node N)
    {
        // increase by one as before
        N.num++;
        // change the reference to a new object
        N = new Node();
        System.out.println("num value is:" + N.num);
    }

    public static void main(String args[])
    {
        Node N = new Node() ;
        TestPassByReference T  = new TestPassByReference() ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;
        T.increaseByOne(N) ;
        System.out.println("num = "+N.num) ;

       // now try this method to see the difference
       T.increaseByOneThenChange(N);
       // N here is the original object, whose `num` value was incremented
       // but the reference remains unchanged by the above method
       System.out.println("num = "+N.num) ;
    }
}

在第二种情况下,只有传递给方法的引用发生变化,因此仅在方法主体中可见(N 将不再引用原始对象),但原始对象仍然是一样。