java Boolean value not changing in called method

37,330

Solution 1

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. Everything is passed by value.

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

Here's a good article about it: 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.

Or use MutableBoolean from Apache Commons Lang.

Solution 2

The problem is that you are reassigning b in 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.

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

Share:
37,330
user1849060
Author by

user1849060

I am a front end developer working with React Native.

Updated on April 16, 2020

Comments

  • user1849060
    user1849060 about 4 years

    I have a scenario where I want to set a Boolean object 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.

    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 CustomObject creation b.booleanValue() is always true, even if the if-statement in callingMethod() is true and the Boolean is set to false in that method.

    I am reluctant to change the return type of the calling method to be a boolean as 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)

  • S. Buda
    S. Buda about 8 years
    That link was really insightful. I'd encourage any java programmer that sees this to read it.
  • user1169587
    user1169587 about 7 years
    why convert b to a field can make b in calling method change in called method?
  • rob
    rob about 7 years
    If you convert b to a field (i.e., it is no longer a parameter but is made visible to the called method), both the calling method and called method are referencing the same variable; whereas if b is a parameter, the calling method and called method are referencing 2 different variables.