【问题标题】:Changing the values of variables in methods, Java [duplicate]更改方法中变量的值,Java [重复]
【发布时间】:2010-10-04 03:29:24
【问题描述】:

我有一个关于在 Java 中更改方法中的变量值的问题。

这是我的代码:

public class Test {
    public static void funk(int a, int[] b) { 
        b[0] = b[0] * 2; 
        a = b[0] + 5;
    } 

    public static void main(String[] args) {
        int bird = 10;
        int[] tiger = {7};

        Test.funk(bird, tiger);
    }
}

Test.funk(bird, tiger)方法执行后,bird的值没有改变——它仍然是10,即使在funk()方法中我们已经用a = b[0] + 5;改变了值

另一方面,数组中元素的值发生变化,因为我们有声明b[0] = b[0] * 2;

我不明白为什么一件事会改变而另一件事不会?谁能帮我解释一下。

【问题讨论】:

    标签: java scope


    【解决方案1】:

    查看 Jon Skeet 关于Parameter-Passing in Java 的文章,其中解释了这一点。

    简而言之(查看他的网站以获得更全面的解释):

    数组是引用类型。如果传递指向数组的引用,则引用的值将被复制并分配给函数的参数。所以参数将指向与传递的参数相同的数组。因此,您通过函数的参数对数组所做的更改将在调用函数中可见。但是,更改参数本身 (b),例如将其设置为 null,调用函数不会注意到,因为参数 (b) 只是参数 (tiger) 的副本通过了。

    整数是所谓的原始类型。传递整数会复制其值并将其分配给参数。但该值不是对实际数据的引用,而是数据本身。所以函数中参数的改变会影响参数(a),但不会影响调用函数(bird)中传递的参数。

    【讨论】:

      【解决方案2】:

      基本上,对象(如数组)是“通过引用”传递给方法的。因此,当您更改对象时,它会更改传递给方法的同一对象。

      基元(如 int)是“按值传递”的,因此您在 a 中分配值的变量与传入的 int 变量不同。

      我希望这会有所帮助...

      【讨论】:

      • 不,它没有帮助。 Java 总是按值传递。阅读其他答案中提供的链接;你需要明白这一点。
      • 对于这个例子,我的“基本”解释很好。我明确表示这是一个基本的解释。如果提问者想阅读更深入的解释,链接就在那里。我不知道他需要多少细节,所以我想他可能会喜欢这个选择。
      • 是的,我很感激。我也阅读了链接,但简短的解释也有助于您入门。谢谢大家。
      【解决方案3】:

      那是因为当你声明

       public static void funk(int a, int[] b) 
      

      变量a的作用域只是那个方法。然后,当您更改值时,您仅更改 that 方法中的 that 变量的值。

      关于 b.那是对 main 中创建的同一数组的新对象引用,这就是为什么它似乎值确实发生了变化(正在变化的是下面的数组对象)

      但是试试这个:

      public static void funk(int a, int[] b) { 
          // create a new reference for b
          int[] c = new int[b.length];
          c[0] = b[0];
          b = c;
      
          // The same.
          b[0] = b[0] * 2; 
          a = b[0] + 5;
      } 
      

      当你这样做时,你的 Tiger 的值也不会改变(只有在 funk 中创建的新数组 c 的内容)

      您可以使用包装器模拟通过 ref 传递。 See this post.

      虽然我没有任何关于这方面的知识

      编辑只是为了好玩:

      我已修改您的代码以使用上面发布的包装器。

      它看起来很奇怪,但看起来很有效。

      // By ref simulated.
      public class Test {
      
          public static void funk(_<Integer> a, int[] b) { 
              b[0] = b[0] * 2; 
              a.s(  b[0] + 5 ) ;
          } 
      
          public static void main(String[] args) {
              _<Integer> bird = new _<Integer>(10);
              int[] tiger = {7};
      
              Test.funk( bird , tiger );
      
              System.out.println("bird = " + bird );
              System.out.println("tiger = " + tiger[0] );
      
          }
      
      }
      

      打印

      bird = 19
      tiger = 14
      

      :-S

      【讨论】:

        【解决方案4】:

        一个变量是通过引用传递,另一个是通过值:)

        What's the difference between passing by reference vs. passing by value?

        【讨论】:

        猜你喜欢
        • 2013-05-06
        • 1970-01-01
        • 1970-01-01
        • 2019-02-25
        • 2015-12-30
        • 2019-07-31
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        相关资源
        最近更新 更多