java布尔值在被调用的方法中没有改变

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36649522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:31:29  来源:igfitidea点击:

java Boolean value not changing in called method

javapass-by-referencepass-by-value

提问by user1849060

I have a scenario where I want to set a Booleanobject and then use its booleanValue()in a constructor later on in the method. However, the scope in which the object is set is different. It is set in a method called by the method in which the object is first instantiated. Based on my understanding of how Java passes primitive and object arguments and reading several posts online (such as this), when an object is passed into a method, its properties are passed by reference and any change in the called method should be reflected in the calling method after the called method has finished execution. However I am noticing that when the called method is finished, any change in there is not taking effect in the calling method.

我有一个场景,我想设置一个Boolean对象,然后booleanValue()在方法中稍后在构造函数中使用它。但是,对象设置的范围不同。它被设置在一个方法中,该方法被首先实例化对象的方法调用。基于我对Java如何传递原始和对象参数的理解以及在线阅读了几篇文章(例如this),当一个对象被传递给一个方法时,它的属性是通过引用传递的,被调用方法的任何变化都应该反映在在被调用方法执行完毕后调用方法。但是我注意到当被调用的方法完成时,调用方法中的任何更改都不会生效。

Here is a snapshot of my scenario:

这是我的场景的快照:

private CustomObject1 callingMethod(){
    Boolean b = Boolean.TRUE;
    List<CustomObject2> list = this.calledMethod(b);
    //Create CustomObject1 with b.booleanValue() as one of the arguments in the constructor
}

private List<CustomObject2> calledMethod(Boolean b){
    ...
    ...
    if(condition){
        b = Boolean.FALSE;
    }
    ...
    ...
}

By the time the code reaches the CustomObjectcreation b.booleanValue()is always true, even if the if-statement in callingMethod()is true and the Booleanis set to false in that method.

到代码到达CustomObject创建时b.booleanValue()总是为真,即使 if 语句中的callingMethod()为真并且Boolean在该方法中设置为假。

I am reluctant to change the return type of the calling method to be a booleanas it would require changes in other bits of code that may call this method. Currently they only need a signature change but a return type change would require more work as the logic needs to be maintained (i.e populating a list and then doing something with it)

我不愿意将调用方法的返回类型更改为 a,boolean因为它需要更改可能调用此方法的其他代码位。目前他们只需要更改签名,但更改返回类型需要更多的工作,因为需要维护逻辑(即填充列表然后用它做一些事情)

采纳答案by ericbn

First, there is a lot of misinformation about parameter passing in Java, like "objects are passed by reference, primitives are passed by value" which is not true. Everythingis passed by value.

首先,在 Java 中存在很多关于参数传递的错误信息,例如“对象通过引用传递,基元通过值传递”,这是不正确的一切都是按值传递

You're not passing an object by reference in Java, you're passing an object reference by value. Boolean bdoes not hold a Booleanobject, it holds a reference (a pointer) to a Booleanobject.

您不是在 Java 中通过引用传递对象,而是通过值传递对象引用。Boolean b不持有一个Boolean对象,它持有一个对象的引用(一个指针)Boolean

Here's a good article about it: http://javadude.com/articles/passbyvalue.htm

这是一篇关于它的好文章:http: //javadude.com/articles/passbyvalue.htm

Second, Boolean(like the other wrapper objects and also String) are immutable objects. So with an immutable object, and as they are passed by value (better said, their references are passed by value), you cannot achieve what you desire. You'll need to have a mutable object instead, like @rob mentioned.

其次,Boolean(和其他包装对象一样String)是不可变对象。因此,对于不可变对象,并且由于它们是按值传递的(更好的说法是,它们的引用是按值传递的),因此您无法实现您的愿望。您需要有一个可变对象,就像提到的@rob 一样。

Or use MutableBooleanfrom Apache Commons Lang.

或者MutableBooleanApache Commons Lang 使用

回答by rob

The problem is that you are reassigning bin calledMethod. A reassignment in calledMethod only reassigns the variable declared in that method's parameter list; it does not modify the variable declared in the caller's scope.

问题是您正在b调用的方法中重新分配。在 calledMethod 中重新分配只会重新分配在该方法的参数列表中声明的变量;它不会修改在调用者作用域中声明的变量。

To do what you want to achieve, you could either convert bto a field, or create a MutableBoolean class which allows you to do something like b.setValue(false).

要完成您想要实现的目标,您可以转换b为一个字段,或者创建一个 MutableBoolean 类,它允许您执行类似b.setValue(false).