开发者

change a functions argument's values?

开发者 https://www.devze.com 2023-02-23 14:00 出处:网络
This may seem like a stupid question, but would this function actually affect t开发者_如何学编程he variable bool (there is greater context to how I\'m going to use this, but this is basically what I\'

This may seem like a stupid question, but would this function actually affect t开发者_如何学编程he 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;
    }
}


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.


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


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]


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


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


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'.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号