Home > Back-end >  String value in Optional is overwrite
String value in Optional is overwrite

Time:12-29

I've been working with Optional in Java. However, in one of my tests, I realized something odd had happened. When I execute the following code:

import java.util.Optional;

public class OptionalTest {
    static String globalString = "Hello";

    public static void main(String... optional) {
        String otherString = "Other";
        globalString  = Optional.of(otherString)
            .orElse(updateString());
        System.out.println(globalString);
    }

    static String updateString() {
        System.out.println("It's called");
        globalString = "Not Hello";
        return "Another";
    }
}

I got the following result:

It's called
HelloOther

Instead of:

It's called
Not HelloOther

I can't figure out how if the updateString() method is called, the globalString has the same initial value when the Optional result is resolved.

Could someone explain this behavior? Thanx in advance.

CodePudding user response:

The concat operation evaluates globalString before the update happens. Essentially, it translates to this:

String part1 = globalString; // Hello
String part2 = Optional.of(otherString).orElse(updateString()); // Other
globalString = part1   part2; // HelloOther

What happens to inside updateString() has no effect on the end result.

CodePudding user response:

According to the spec, this is what a compound assignment does at runtime. Relevant parts only (emphasis mine):

If the left-hand operand expression is not an array access expression, then:

  • First, the left-hand operand is evaluated to produce a variable.

  • the value of the left-hand operand is saved and then the right-hand operand is evaluated.

  • the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator.

  • the result of the binary operation is converted to the type of the left-hand variable, and the result of the conversion is stored into the variable.

As you can see, the value of globalString before calling updateString is saved first, and only then is the RHS evaluated. It is not: RHS is evaluates, and then globalString is evaluated to see what the result should be appended to.

In general, evaluation in Java happens left to right, so even if you use a simple assignment, it still would not be your expected output:

globalString = globalString   Optional.of(otherString)
    .orElse(updateString());

The second globalString is evaluated first. Then updateString is called, setting globalString. With both operands evaluated, is evaluated to the string HelloOther, to which globalString is set to.

  • Related