21

This may seem like a stupid question, but would this function actually affect the variable bool (there is greater context to how I'm going to use this, but this is basically what I'm unsure about)? (I am asking specifically about java)

void truifier (boolean bool) {
    if (bool == false) {
        bool = true;
    }
}
LRFLEW
  • 1,251
  • 3
  • 11
  • 19

7 Answers7

26

Consider a slightly different example:

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);
    }
}

The output from running this program would be:

bool is true
in is false

The bool variable would be changed to true, but as soon as the truifier method returned, that argument variable goes away (this is what people mean when they say that it "falls out of scope"). The in variable that was passed in to the truifier method, however, remains unchanged.

pohl
  • 3,158
  • 1
  • 30
  • 48
  • 2
    Thanks. This explains what I was asking about. Thanks. – LRFLEW Apr 09 '11 at 20:58
  • 4
    To clarify, the bool variable does not change in the calling method. A new copy of the variable is created in the called method. You can change it as much as u like, but this var is different from the one in calling method. Yet, if your argument was a pointer, then any changes in the called method will directly affect the object in the calling method, since a new copy of the variable is not created in the called method. – euphoria83 Apr 09 '11 at 21:11
  • @pohl is there any way in java I can pass a variable in method and get the updated value from method? [Except the case when i pass object's reference and update the object, or I return the updated value] – AKS Aug 16 '13 at 18:59
  • 2
    @AKS The only way to accomplish this in Java would be to pass a reference to an object with a mutable field, allowing the method to mutate the object's field. – pohl Aug 16 '13 at 19:39
  • 6
    Thanks pohl!! Was able to do it using passing an object. But its really surprising and quiet important to know tht java works as passing by value. It passes value in case of primitives and value of reference in case of objects. In case of primitives, value can not be changed. and in case of references, value of object can be modified but can not be assigned to new object.I was hitting my head on wall that why my primitive argument which i am passing in my recursive function is not being updated. :) .. – AKS Aug 17 '13 at 10:04
20

As another response pointed out, when passed as a parameter, a boolean will be created locally for your truifier function, but an object will be referenced by location. Hence, you can get two very different results based on what parameter type you are using!

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
    }
}

If however you are not using a boolean, but an Object, a parameter can then modify an object. //THIS CODE OUTPUTS TRUE

Max Alexander Hanna
  • 3,388
  • 1
  • 25
  • 35
4
void truifier (boolean bool) {
    if (bool == false) {
        bool = true;
    }
}

void demo () {
    boolean test = false;
    truifier (test); 
    // test is still false
    System.out.println (test);
}

You know you can call the function with a literal constant - what should be modified here?

void demo2 () {
    truifier (false); 
}

Or with a final local variable

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

Or with Attributes from a class:

class X {
    private boolean secret = false; 

    void demo3 () {
        truifier (secret); 
    }
}

In all these calls, truifier gets a local copy of the reference to the object in question.

boolean b = false;
// b -> false  

b is a reference to the object "false" - or in this case primitive value.

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

c is changed, but not b. c isn't an alias for b, but a copy of the reference, and now the copy references a true. There are only 2 real objects (primitives) here: true and false.

In a method call, a copy of the reference is made and passed, and changes on that reference affect only this. However, there is no deep copying. With a class, for which you change an attribute, will have that attribute changed outside, but you can't replace the class itself. Or Arrays: You may change the content of the array (the reference-copy points to the same array) but not the array itself (the size, for instance). Well - you can change it in the method, but the outer reference is independent, and not changed.

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]
user unknown
  • 35,537
  • 11
  • 75
  • 121
1

Yes it would, only in the scope of the function.

Val
  • 173
  • 2
  • 10
  • "in the scope of the function" so it won't actually change the value of the variable given in the function? – LRFLEW Apr 09 '11 at 20:45
  • 1
    if you print the bool value after the if statement you should get true, if false was passed in. – Val Apr 09 '11 at 20:46
  • so let me get this strait. `void truifier (boolean bool) { bool = true; System.out.println(bool)}` will print true, but `new boolean bool; truifier(bool); System.out.println(bool)` will print false – LRFLEW Apr 09 '11 at 20:48
  • @bmargulies illustrated it pretty well. But, yes your comments is true. Primitive booleans are false by default, and your method modifies the value only in the scope of the function. – Val Apr 09 '11 at 20:55
1

Yes, in the scope of the method. But assigning method arguments is sometimes considered a bad practice which reduces code readability and makes it more error-prone. You should consider creating new boolean variable within the method body and assigning the parameter to it.

Also, your example can be rewritten like this:

if (!bool) {
    bool = true;
}
janhink
  • 4,943
  • 3
  • 29
  • 37
0

It appears that the original question is about 'call by reference' or the lack thereof.

To make this clearer, consider:

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

This will print 'false'.

A similiar call at the end of trueifier will print 'true'.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
0

You can do this trick :

Firstly, you englobe the boolean variable with a class

class MyBoolean {
private boolean b;
}

Secondly, you add a suitable constructor :

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

Then, you add 2 methods: get and alter; the get method returns the current value of the boolean variable and the alter method toggle its value.

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+"";
    }
}

So, instead of defining a boolean variable, you define a MyBoolean Object.

Then you pass this object to your "truifier" function, with a little change on it :

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

And finally, the value of the boolean variable inside "b" object is changed now.

user9152856
  • 99
  • 1
  • 9