【问题标题】:If Java is a "call-by-value" language then why is this happening?如果 Java 是一种“按值调用”语言,那么为什么会发生这种情况?
【发布时间】:2017-08-07 05:57:18
【问题描述】:

查看测试代码:

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 object reference pass-by-value


【解决方案1】:

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

    【讨论】:

      【解决方案3】:

      在您的代码中,您有一个 Node 类的 Object 。

      保持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
      

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-01-24
          • 1970-01-01
          • 2021-06-12
          • 2021-04-30
          • 2010-09-22
          • 1970-01-01
          • 2013-12-09
          相关资源
          最近更新 更多