如果 Java 是一种“按值调用”语言,那么为什么会发生这种情况?

问题描述 投票:0回答:4

参见测试代码:

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

这里的问题是,由于

Java
call by value
,那么
num
Node
属性应该保持为0。

我认为这是由于创建了一个对象

T
,该对象本来包含一个对象
N
。但是
T
中没有属性来保存类似
Node
的对象。那么这是怎么发生的呢?

我们非常感谢任何帮助。

月亮。

java object reference pass-by-value
4个回答
4
投票

Java 通过引用传递对象。

Node N
是一个对象。因此,当您执行
N.num++
时,您将增加同一对象的整数。


2
投票

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
此处将不再引用原始对象),但原始对象保持不变。


0
投票

在您的代码中,您有 Node 类的单个对象。

保存

num
的值,初始值为 0, 当调用函数并递增
num
的值时,每次
num
的值都会增加,因为相同的 Node 类对象。它很容易理解,节点对象是 Node 类的实例,如果你创建另一个 Node 类对象,它将是不同的类实例。

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

0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.