【问题标题】:Java: pass-by-value references in methodsJava:方法中的按值传递引用
【发布时间】:2014-09-08 16:27:39
【问题描述】:

我在 Stackoverflow 中阅读了几篇文章和类似的问题;但是,我并没有完全得到我的问题的答案。 代码如下:

public class CoinFlipping {

    Random random = new Random();

    Boolean head = null;

    public void flip(Boolean b){
        b = random.nextBoolean();
    //      head = b; 
    }

    public static void main(String [] args){
        CoinFlipping cf = new CoinFlipping();
        cf.flip(cf.head);
        System.out.println("Head: "+cf.head);
    }

    }

我参考这篇文章:Is Java "pass-by-reference" or "pass-by-value"? 我可以理解为什么那段代码的行为如此。当我们调用new dog() 时,我们基本上创建了一个新的 Dog 对象。我知道了。但是,我提供的示例似乎有点令人困惑。在这种情况下,我没有创建对象(不是吗?)。我正在改变一个值。那么为什么在这种情况下,当我打印结果时,我得到的是null 而不是truefalse

【问题讨论】:

  • b = random.nextBoolean(); 创建一个新引用,因此修改b 的值,而不是b 引用的值。
  • @AntonH: b 没有“引用一个值”。 b 具有一个值,它是对对象的引用(或空引用)。赋值语句给 b 一个新值(即对新对象的引用)。
  • @jameslarge 我试图简化,以便 OP 看到问题所在。但显然太多了。
  • 链接问题的答案直接解决了这个问题。请参阅stackoverflow.com/a/40507/217324 将其作为副本关闭。
  • @AntonH 你好,我说对了吗?当我将任何对象传递给方法时,会发生以下情况:它通过引用查找对象的值,复制它并将这个副本分配给本地 var(参数)?在这种情况下,我还有另一个问题。有什么方法可以传递对方法的引用,以便我可以获取这个引用、访问对象并更改它的内部状态?有没有办法实际引用原始对象但不在方法内部复制?

标签: java pass-by-reference pass-by-value


【解决方案1】:

参数b 是按值传递的,即使b 本身就是一个引用。因此,当您调用flip 时,flip 方法将b 视为一个局部变量,它是您传递给它的内容的副本。更改此副本不会更改 cf.head

如果b 是对可变对象的引用,您可以更改b 引用的对象,并且在flip 返回后程序的其余部分将看到该更改。但是对b 的更改本身就是对副本的更改,任何此类更改都不会被程序的其余部分看到。 (Boolean 不可变。)

【讨论】:

    【解决方案2】:

    回答你的问题:

    那么为什么在这种情况下,当我打印结果时,我得到 null 而不是 truefalse

    我已经为您的代码创建了一个分步演练,以向您展示特定变量的指针(引用)并回答为什么它最终会打印出null

    1.步骤:使用默认字段值创建新的 CoinfFlipping 对象

    CoinFlipping cf = new CoinFlipping();
    

    CoinFlipping 类内部:

    Random random = new Random();
    Boolean head = null;
    

    cf ---- 指向 ----> CoinFlipping 对象
    cf.random ---- 指向 ----> Random 对象
    cf.head -- -- 指向 ----> null


    2.步骤:在cf对象上以cf.head作为参数调用flip方法

    cf.flip(cf.head);
    

    调用此方法时,会在flip 方法的范围内创建一个变量b。 来自cf.head 的指针(引用)被复制到变量b 中。 所以cf.headb 指向同一件事。

    public void flip(Boolean b){
    

    cf ---- 指向 ----> CoinFlipping 对象
    cf.random ---- 指向 ----> Random 对象
    cf.head -- -- 指向 ----> null
    b ---- 指向 ----> null


    3.步骤:在 flip 方法内部 b 正在重新分配

    b = random.nextBoolean();
    

    cf ---- 指向 ----> CoinFlipping 对象
    cf.random ---- 指向 ----> Random 对象
    cf.head -- -- 指向 ----> null
    b ---- 指向 ----> boolean 值 - truefalse

    4。步骤:回到main方法打印出cf.head

    System.out.println("Head: "+cf.head);
    

    cf ---- 指向 ----> CoinFlipping 对象
    cf.random ---- 指向 ----> Random 对象
    cf.head -- -- 指向 ----> null
    b ---- 指向 ----> boolean 值 - truefalse

    如您所见,cf.head 仍指向null,因此正在打印null

    解决办法:
    要改变这一点,您可以让该方法返回一个布尔值,并将其分配给cf.head,以使cf.head 指向一个新的布尔值。

    【讨论】:

      猜你喜欢
      • 2021-11-04
      • 2014-09-10
      • 2013-07-22
      • 2016-11-28
      • 2013-12-02
      相关资源
      最近更新 更多