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.