...
Java programming language implementations must respect the order of evaluation as indicated explicitly by parentheses and implicitly by operator precedence.
These When an expression contains side effects, these two requirements can be counter-intuitive when expressions contain side effectsyield surprising results. Evaluation of the operands proceeds left-to-right, without regard to operator precedence rules and indicative parentheses; evaluation of the operators, however, obeys precedence rules and parentheses.
Expressions must not write to memory that they subsequently read, and also must not write to any memory twice. Note that memory writing and reading can occur either directly in the expression from assignments or indirectly through side effects in functions methods called in the expression.
...
This noncompliant code example shows how side effects in expressions can lead to unanticipated outcomes. The programmer intends to write access control logic based on different threshold levels. Each user has a rating that must be above the threshold to be granted access. As shown, a simple function method can calculate the rating. The get()
method is expected to return a non-zero factor for users who are authorized, and a zero value for those who are unauthorized.
...
Code Block | ||
---|---|---|
| ||
int number = 17; final int authnum = get(); number = ((31 * (number + 1)) * authnum) + (authnum > threshold[0]? 0 : -2); |
Exceptions
EXP05-EX0: The prefix increment and prefix decrement operators (++
and --
) read a numeric variable, and then assign a new value to a the variable and then subsequently read it. These are well-understood and are an exception to the rule against reading memory that was written in the same expressionthis rule.
EXP05-EX1: The logical operators ||
and &&
have well-understood short-circuit semantics, so expressions involving these operators may do not violate this rule. Consider the following code:
Code Block | ||
---|---|---|
| ||
public void exampleFunctionexampleMethod(InputStream in) { int i; // Skip one char, process next while ((i = in.read()) != -1 && (i = in.read()) != -1) { // ... } } |
...
EXP30-C. Do not depend on order of evaluation between sequence points | ||||
EXP30-CPP. Do not depend on order of evaluation between sequence points | ||||
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="efc36741f019937c-cac2d735-4d3a4f0a-95f29e02-d9cf8c9f9d8d34de352e2493"><ac:plain-text-body><![CDATA[ | [ISO/IEC TR 24772:2010 | http://www.aitcnet.org/isai/] | "Side?effects and Order of Evaluation [SAM]" | ]]></ac:plain-text-body></ac:structured-macro> |
...
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="d8567a9f31f77a5b-6286b9ef-42034158-a6cb8130-0c7f4dd0cd2ab94605960897"><ac:plain-text-body><![CDATA[ | [[JLS 2005 | AA. Bibliography#JLS 05]] | [§15.7, "Evaluation Order" | http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7] | ]]></ac:plain-text-body></ac:structured-macro> |
|
...