简体   繁体   English

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

[英]If Java is a “call-by-value” language then why is this happening?

See the test code: 查看测试代码:

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) ;
    }
}

Which gives the result: 结果如下:

num = 1
num = 2
num = 3

The problem here, is that since Java is call by value then the num attribute of Node should have remained 0. 这里的问题是,由于Javacall by value ,因此Nodenum属性应该保持为0。

I think that this is due to creation of an object T , which would have contained an object N . 我认为这是由于创建了对象T所致,该对象本可以包含对象N But there is no attribute in T to save a Node like object. 但是T没有属性可以保存类似Node对象。 So how is this happening? 那怎么回事呢?

Any help is nefariously appreciated. 非常感谢任何帮助。

Moon. 月亮。

Java passes objects by reference. Java通过引用传递对象。 Node N is an object. Node N是一个对象。 So when you do N.num++ you're incrementing the same object's integer. 因此,当您执行N.num++您将递增同一对象的整数。

Java is call-by-value in the sense that references are passed-by-value. Java是按值调用,即references是按值传递的。

This means you can change the internal state of the object you passed N (eg by modifying the num field's value) but you cannot reassign N to a new object (eg N = null; or N = new Node(); ). 这意味着您可以更改传递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) ;
    }
}

In the second case, only the reference that was passed to the method changes thus being visible only in the method's body ( N will no longer refer the original object here), but the original one remains the same. 在第二种情况下,仅传递给该方法的引用会更改,因此仅在该方法的主体中可见( N在这里不再引用原始对象),但是原始引用保持不变。

In your code you have single Object of class Node . 在您的代码中,您只有Node类的Object。

That holds value of num with initial value 0, And when call function and increment value of num each time value of num will be increase because same Node class object . 持有的价值num初始值0,而当呼叫功能和增值num的每一时间值num将增加,因为同一节点的类对象。 its simple to understand node object is instance of class Node if you make another Node class object it will different instance of class . 它的节点对象简单易懂,它是Node类的实例。如果您创建另一个Node类对象,它将是不同的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) ;
    }
}

Then out come is : 然后出来的是:

num = 1
num = 2
num = 1

well, you are creating single object of Node and TestPassByReference so T referes the same Node reference which you cloud create earlier. 好吧,您正在创建Node和TestPassByReference的单个对象,因此T引用了您先前云创建的同一Node引用。 So the same value is increaments when you call the method. 因此,调用该方法时,相同的值是increaments。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM