【问题标题】:change a functions argument's values?更改函数参数的值?
【发布时间】:2023-03-14 13:24:01
【问题描述】:

这似乎是一个愚蠢的问题,但这个函数实际上会影响变量bool(我将如何使用它有更多的上下文,但这基本上是我不确定的)? (我是专门问java的)

void truifier (boolean bool) {
    if (bool == false) {
        bool = true;
    }
}

【问题讨论】:

    标签: java function


    【解决方案1】:

    考虑一个稍微不同的例子:

    public class Test {
    
        public static void main(String[] args) {
            boolean in = false;
            truifier(in);
            System.out.println("in is " + in);
        }
    
        public static void truifier (boolean bool) {
            if (bool == false) {
                bool = true;
            }
            System.out.println("bool is " + bool);
        }
    }
    

    运行这个程序的输出是:

    bool is true
    in is false
    

    bool 变量将被更改为 true,但是一旦 truifier 方法返回,该参数变量就会消失(这就是人们说它“超出范围”时的意思)。但是,传递给 truifier 方法的 in 变量保持不变。

    【讨论】:

    • 谢谢。这解释了我在问什么。谢谢。
    • 为了澄清,bool变量在调用方法中没有改变。在被调用的方法中创建变量的新副本。你可以随心所欲地改变它,但这个 var 与调用方法中的不同。然而,如果您的参数是一个指针,那么被调用方法中的任何更改都会直接影响调用方法中的对象,因为在被调用方法中不会创建变量的新副本。
    • @pohl 在java中有什么方法可以在方法中传递一个变量并从方法中获取更新的值吗? [除非我传递对象的引用并更新对象,或者我返回更新的值]
    • @AKS 在 Java 中实现此目的的唯一方法是传递对具有可变字段的对象的引用,从而允许该方法改变对象的字段。
    • 谢谢波尔!!能够通过传递一个对象来做到这一点。但是知道 java 是按值传递的,这真的很令人惊讶和安静。它在原语的情况下传递值,在对象的情况下传递参考值。在原语的情况下,值不能改变。并且在引用的情况下,可以修改对象的值,但不能将其分配给新对象。我正撞在墙上,为什么我在递归函数中传递的原始参数没有被更新。 :) ..
    【解决方案2】:

    正如另一个响应指出的那样,当作为参数传递时,将为您的 truifier 函数在本地创建一个布尔值,但将通过位置引用一个对象。因此,根据您使用的参数类型,您可以获得两种截然不同的结果!

    class Foo {
        boolean is = false;
    }
    class Test
    {
        
        static void trufier(Foo b)
        {
            b.is = true;
        }
        public static void main (String[] args)
        {
            // your code goes here
            Foo bar = new Foo();
            trufier(bar);
            System.out.println(bar.is); //Output: TRUE
        }
    }
    

    但是,如果您使用的不是布尔值,而是对象,则参数可以修改对象。 //这段代码输出为真

    【讨论】:

    • 这个答案而不是接受的答案提供了对 OP 中隐含问题的解释。
    【解决方案3】:
    void truifier (boolean bool) {
        if (bool == false) {
            bool = true;
        }
    }
    
    void demo () {
        boolean test = false;
        truifier (test); 
        // test is still false
        System.out.println (test);
    }
    

    你知道你可以用文字常量调用函数——这里应该修改什么?

    void demo2 () {
        truifier (false); 
    }
    

    或者使用最终的局部变量

    void demo2 () {
        final boolean b = false;
        truifier (b); 
    }
    

    或者使用类中的属性:

    class X {
        private boolean secret = false; 
    
        void demo3 () {
            truifier (secret); 
        }
    }
    

    在所有这些调用中,truifier 获取对相关对象的引用的本地副本。

    boolean b = false;
    // b -> false  
    

    b 是对对象“false”的引用——或者在这种情况下是原始值。

    boolean c = b; 
    // c -> false, not: c-> b -> false
    c = true; 
    // c -> true
    

    c 已更改,但 b 未更改。 c 不是 b 的别名,而是引用的副本,现在该副本引用了 true。这里只有 2 个真实对象(基元):真和假。

    在方法调用中,会创建并传递引用的副本,并且对该引用的更改仅影响此。但是,没有深度复制。对于您更改属性的类,该属性将在外部更改,但您不能替换类本身。或数组:您可以更改数组的内容(引用副本指向同一个数组),但不能更改数组本身(例如大小)。好吧-您可以在方法中更改它,但是外部引用是独立的,不会更改。

    k = [a, b, c, d]
    l = k; 
    l [2] = z;
    // l=k=[a, b, z, d]
    l = [p, q, r]
    // k = [a, b, z, d]
    

    【讨论】:

      【解决方案4】:

      是的,只是在函数的范围内。

      【讨论】:

      • “在函数范围内”所以它实际上不会改变函数中给定变量的值?
      • 如果你在 if 语句之后打印 bool 值,你应该得到 true,如果传入的是 false。
      • 所以让我解决这个问题。 void truifier (boolean bool) { bool = true; System.out.println(bool)} 将打印 true,但 new boolean bool; truifier(bool); System.out.println(bool) 将打印 false
      • @bmargulies 很好地说明了这一点。但是,是的,你的 cmets 是真的。原始布尔值默认为 false,您的方法仅在函数范围内修改值。
      【解决方案5】:

      是的,在方法的范围内。但是分配方法参数有时被认为是一种不好的做法,它会降低代码的可读性并使其更容易出错。您应该考虑在方法体中创建新的布尔变量并将参数分配给它。

      另外,您的示例可以这样重写:

      if (!bool) {
          bool = true;
      }
      

      【讨论】:

        【解决方案6】:

        看来最初的问题是关于“通过引用调用”或缺少它。

        为了更清楚地说明这一点,请考虑:

         void caller() {
            boolean blooean = false;
            truifier(blooean);
            System.err.println(blooean);
         }
        

        这将打印“假”。

        在 trueifier 末尾的类似调用将打印 'true'。

        【讨论】:

          【解决方案7】:

          你可以做到这一点:

          首先,将布尔变量与一个类结合起来

          class MyBoolean {
          private boolean b;
          }
          

          其次,你添加一个合适的构造函数:

          class MyBoolean {
          private boolean b;
          public MyBoolean(boolean b) {
          this.b = b;
          }
          

          然后,添加 2 个方法:get 和 alter; get 方法返回 布尔变量的当前值和 alter 方法切换它的值。

          class MyBool {
                  private boolean b;
                  public MyBool(final boolean b) { this.b = b; }
                  public boolean getValue() { return b; }
                  public void alter() { 
                      if(b == true) {
                          b = false;
                          return;
                      }
                      b = true;
                  }
          
              @Override
              public String toString() {
                  return b+"";
              }
          }
          

          因此,您无需定义布尔变量,而是定义 MyBoolean 对象。

          然后你将这个对象传递给你的“truifier”函数,并对其稍作改动:

          public static void truifier(MyBoolean b) {
          b.alter();
          } 
          

          最后,“b”对象内的布尔变量的值现在改变了。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-11-27
            • 2021-08-15
            • 1970-01-01
            • 1970-01-01
            • 2012-02-23
            • 2019-02-05
            • 2011-07-14
            • 1970-01-01
            相关资源
            最近更新 更多