Study guide
1.3 Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation
Oracle Java SE 17 Developer Certified Professional 1Z0-829
Track your progress as you read
Finished sections get a check mark.
1 Introduction: The 1Z0-829 Exam
About the Java SE 17 Developer (1Z0-829) Exam
2 Chapter 1: Java Fundamentals & Language Basics
1.1 Primitive Types, Literals, Wrapper Classes, and Type Promotion/Casting 1.2 Local Variable Type Inference (`var`) Rules and Scoping 1.3 Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation 1.4 Text Blocks, String Immutability, and StringBuilder APIs
3 Chapter 2: Program Flow & Decision Constructs
2.1 Conditional Branching with if/else and the Ternary Operator 2.2 Switch Statements and Switch Expressions 2.3 Iteration Constructs, Loop Control, and Branching Labels
4 Chapter 3: Object-Oriented Design & Class Mechanics
3.1 Class Declarations, Field/Method Signatures, and Access Modifiers 3.2 Constructors, Overloading, Initialization Order, and Garbage Collection 3.3 Inheritance, Method Overriding, Polymorphism, and `super`/`this` 3.4 Abstract Classes, Static Members, and Object Methods (`equals`, `hashCode`, `toString`)
5 Chapter 4: Advanced OOP: Interfaces, Records & Sealed Types
4.1 Interface Architecture: Default, Static, and Private Methods 4.2 Enumerations: Constants, Constructors, Methods, and Custom Bodies 4.3 Records: Canonical/Compact Constructors, Components, and Immutability 4.4 Sealed Classes and Interfaces: `permits`, Hierarchy Constraints, and Modifiers
6 Chapter 5: Pattern Matching & Nested Types
5.1 Pattern Matching for `instanceof` and Flow Scoping Mechanics 5.2 Nested Types: Member Inner, Static Nested, Local, and Anonymous Classes 5.3 Defensive Programming, Immutability Patterns, and Validation
7 Chapter 6: Generics, Collections & Arrays
6.1 Generic Classes, Interfaces, Methods, and Type Erasure 6.2 Bounded Type Parameters and Wildcards (PECS Rule) 6.3 Collections Framework: List, Set, Queue, and Deque APIs 6.4 The Map Interface, Sorting, Comparable, and Comparator 6.5 Arrays: Declaration, Initialization, Multidimensional Arrays, and the Arrays Utility Class
8 Chapter 7: Functional Programming & Lambda Expressions
7.1 Functional Interfaces and Lambda Syntax Rules 7.2 Standard Functional Interfaces in `java.util.function` 7.3 Method References: Static, Bound, Unbound, and Constructor References
9 Chapter 8: The Stream API
8.1 Stream Lifecycle: Creation, Pipeline Architecture, and Lazy Evaluation 8.2 Intermediate Stream Operations: Filtering, Mapping, Sorting, and Slicing 8.3 Terminal Stream Operations: Reduction, Matching, Finding, and Collecting 8.4 Primitive Streams (`IntStream`, `LongStream`, `DoubleStream`) and Numeric Statistics
10 Chapter 9: Advanced Streams & Collectors
9.1 The Optional Class: Safe Null Handling, Transformation, and Chaining 9.2 The Collectors API: Downstream Reductions, Grouping, and Partitioning 9.3 Parallel Streams: Fork/Join Pool, Spliterators, and Concurrency Pitfalls
11 Chapter 10: Exception Handling
10.1 The Java Exception Hierarchy: Checked vs. Unchecked Exceptions and Errors 10.2 Exception Constructs: `try-catch-finally`, Multi-Catch, and Rethrowing 10.3 Try-With-Resources, `AutoCloseable`, Suppressed Exceptions, and Custom Exceptions
12 Chapter 11: Date/Time API & Localization
11.1 Date and Time Core Types: `LocalDate`, `LocalTime`, `LocalDateTime` 11.2 Timestamps, Intervals, and Durations: `Instant`, `Period`, and `Duration` 11.3 Time Zones, Daylight Saving Time (DST) Offsets, and `ZonedDateTime` 11.4 Internationalization and Localization: `Locale`, `ResourceBundle`, and Formatters 11.5 Formatting and Parsing Messages, Numbers, Percentages, and Localized Dates
13 Chapter 12: Java Platform Module System (JPMS)
12.1 Module Architecture, `module-info.java`, and Module Paths 12.2 Module Directives: `requires`, `requires transitive`, `exports`, and Qualified Exports 12.3 Reflection, Deep Encapsulation, `opens`, and Open Modules 12.4 Services in JPMS (`uses`, `provides...with`), Migration Paths, and Tooling (`jlink`, `jdeps`) 12.5 Compiling and Packaging Code: Non-Modular JARs, Modular JARs, and Migration Strategies
14 Chapter 13: Concurrency & Multithreading
13.1 Thread Fundamentals, `Runnable`, `Callable`, and Thread Lifecycle 13.2 Memory Visibility, `volatile`, Intrinsic Locks, and Synchronization 13.3 The Concurrency Framework: `ExecutorService`, Thread Pools, and `Future` 13.4 Concurrent Collections, Atomic Variables, Explicit Locks, and `CompletableFuture`
15 Chapter 14: Java I/O and NIO.2
14.1 Classical I/O: Byte and Character Streams, Readers, Writers, and Buffering 14.2 Object Serialization, `Serializable`, `transient`, and `serialVersionUID` 14.3 NIO.2 Architecture: `Path`, `Paths`, and Basic `Files` Operations 14.4 Advanced NIO.2: Directory Walking, Streams (`Files.lines`, `walk`), and `WatchService`
16 Chapter 15: Accessing Databases with JDBC
15.1 JDBC Architecture, Drivers, `DriverManager`, and `DataSource` Connections 15.2 SQL Execution: `Statement`, `PreparedStatement`, and `CallableStatement` 15.3 `ResultSet` Navigation, Data Types, and Transaction Management (Commit, Rollback, Savepoints)
17 Chapter 16: Annotations & the Java Logging API
16.1 Standard Annotations: @Override, @FunctionalInterface, @Deprecated, @SuppressWarnings, and @SafeVarargs 16.2 Java Logging API Basics: Logger, Levels, Handlers, and Configuration
1.3 Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation
Key Takeaways Explain This Topic AI
Java operators adhere to a strict precedence hierarchy that parentheses override; postfix increment/decrement binds tighter than prefix unary operators, which bind tighter than binary arithmetic, relational, logical, and assignment operators.
Java guarantees strict left-to-right evaluation of operands before the operator executes; all subexpressions, method arguments, and array indices are evaluated in lexical sequence regardless of operator precedence.
Logical short-circuit operators (&&, ||) skip evaluation of the right-hand operand when the left-hand operand definitively determines the outcome, whereas bitwise/logical operators (&, |, ^) unconditionally evaluate both operands.
The ternary operator (? :) associates from right to left when nested and applies binary numeric promotion across its result branches, which can lead to unexpected unboxing NullPointerExceptions.
Compound assignment operators (+=, -=, *=, /=) embed an implicit narrowing cast back to the target variable's type, masking potential precision loss and integer overflow.
Last updated: October 2026
Operators, Precedence, Evaluation Order, and Short-Circuit Evaluation
Mastering operator interactions requires separating two distinct concepts: operator precedence (which dictates how expressions are grouped into an abstract syntax tree) and operand evaluation order (which dictates the runtime sequence in which expressions are evaluated). The Java Language Specification guarantees deterministic, left-to-right operand evaluation.
Operator Precedence and Associativity Hierarchy
When an unparenthesized expression contains multiple operators, operator precedence determines the grouping of operands with operators. Associativity resolves expressions containing operators of equal precedence:
- Precedence Level Operators Description Associativity
- 1 (Highest) expr++ , expr-- Postfix increment / decrement Left to right
2 ++expr , --expr , + , - , ~ , ! Prefix increment/decrement, unary plus/minus, bitwise complement, logical NOT Right to left
- 3 (type) , new Cast, object creation Right to left
- 4 * , / , % Multiplicative (multiplication, division, remainder) Left to right
- 5 + , - , + (string concat) Additive (addition, subtraction, string concatenation) Left to right
- 6 << , >> , >>> Bitwise shift (signed left, signed right, unsigned right) Left to right
- 7 < , <= , > , >= , instanceof Relational comparison, type comparison Left to right
- 8 == , != Equality and inequality Left to right
- 9 & Bitwise AND / Logical non-short-circuit AND Left to right
- 10 ^ Bitwise XOR / Logical non-short-circuit XOR Left to right
- 11 | Bitwise OR / Logical non-short-circuit OR Left to right
- 12 && Logical short-circuit AND Left to right
- 13 || Logical short-circuit OR Left to right
- 14 ? : Ternary conditional Right to left
- 15 (Lowest) = , += , -= , *= , /= , %= , etc. Assignment and compound assignments Right to left
- Postfix vs. Prefix Evaluation Mechanics
Increment ( ++ ) and decrement ( -- ) operators modify the underlying variable directly:
Prefix ( ++x , --x ) : Increments/decrements the variable first, then yields the new value to the enclosing expression.
Postfix ( x++ , x-- ) : Yields the original value to the enclosing expression, then increments/decrements the variable. int x = 5;
int y = ++x; // x becomes 6, y receives 6
- int a = 5;
- int b = a++; // b receives 5, a becomes 6
- The Classic Self-Assignment Trap
Consider the expression x = x++ :
The current value of x (e.g., 5 ) is stored in an internal evaluation buffer for the right-hand operand.
The postfix increment executes, updating x to 6 in memory.
The assignment operator = executes, writing the buffered value ( 5 ) back into x !
- The net result is that x remains 5 : int val = 10;
- val = val++;
System.out.println(val); // Prints 10!
Left-to-Right Operand Evaluation Order
A critical rule of the Java specification is that operands are evaluated left to right before the operator itself executes , regardless of operator precedence: int a = 2;
- int b = 4;
- int result = a + a * b; // 'a' on the left is evaluated (2), then 'a * b' (2 * 4 = 8), yielding 10
When side effects (such as method calls or increments) are involved, left-to-right evaluation strictly dictates state changes: public class OrderDemo {
- static int compute(String label, int val) {
- System.out.print(label + " ");
- return val;
- }
public static void main(String[] args) {
// In compute("A", 1) + compute("B", 2) * compute("C", 3):
- // compute("A", 1) runs first, then compute("B", 2), then compute("C", 3)
- // Output: A B C (and result is 1 + (2 * 3) = 7)
- int total = compute("A", 1) + compute("B", 2) * compute("C", 3);
- }
- }
- Array Index Evaluation Nuance
In array assignments, the target array reference and the index expression are evaluated before the right-hand side expression: int[] arr = { 10, 20 };
- int idx = 0;
- arr[idx] = idx = 1;
- // Step 1: arr[idx] evaluates idx -> targets arr[0]
- // Step 2: right-hand side evaluates idx = 1 -> sets idx to 1 and yields 1
- // Step 3: assignment stores 1 into arr[0]
- System.out.println(arr[0] + ", " + arr[1]); // Prints 1, 20
- Short-Circuit ( && , || ) vs. Non-Short-Circuit ( & , | )
Java provides two sets of logical operators:
Short-circuit operators ( && , || ) : If the left-hand operand determines the final outcome, the right-hand operand is never evaluated .
For false && expr , expr is skipped.
For true || expr , expr is skipped.
Non-short-circuit operators ( & , | , ^ ) : Both operands are always evaluated , even if the left operand has already determined the logical result.
Warning
Skipped Side Effects in Short-Circuiting If the right-hand side of && or || contains an increment, assignment, or method invocation, that side effect will not occur if the left operand short-circuits. Questions on the exam frequently hide critical state updates on the right side of && . int count = 0;
boolean flag = false;
- if (flag && (++count > 0)) {
- // Not executed
- }
- System.out.println(count); // Prints 0 (increment was never evaluated!)
- if (flag & (++count > 0)) {
- // Not executed, but & forces evaluation of right operand
- }
- System.out.println(count); // Prints 1 (increment was evaluated)
- Bitwise Shift Operators
<< (Signed left shift): Shifts bits left, filling low-order bits with 0 (multiplication by 2 n 2^n 2 n ).
>> (Signed right shift): Shifts bits right, preserving the sign bit (filling high-order bits with 1 for negative numbers, 0 for positive numbers).
>>> (Unsigned right shift): Shifts bits right, always filling high-order bits with 0 , regardless of sign.
Ternary Operator ( ? : ) Type Resolution
The conditional ternary operator takes the form condition ? expression1 : expression2 . If condition is true , expression1 is evaluated; otherwise expression2 is evaluated.
Right-to-Left Associativity
Because the ternary operator associates from right to left, nested ternaries group without parentheses as follows: int score = 75;
- String grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F";
- // Equivalent to: score >= 90 ? "A" : (score >= 80 ? "B" : (score >= 70 ? "C" : "F"))
- Numeric Type Promotion and Unboxing Pitfalls
If the two result expressions of a ternary operator have different numeric types, the compiler applies binary numeric promotion to determine the overall expression type: int n = 5;
double result = true ? n : 2.5; // n is promoted to double (5.0)
// Unboxing NullPointerException Trap:
- Integer boxedNull = null;
- boolean test = false;
int val = test ? 10 : boxedNull; // Evaluates boxedNull, unboxing it to int -> throws NullPointerException!
Compound Assignment Operators and Implicit Narrowing
Compound assignment operators ( += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , >>>= ) provide an automatic narrowing cast:
variable op = expr ⟺ variable = ( TypeOf ( variable ) ) ( variable op expr ) \text{variable } \text{op}=\text{ expr} \iff \text{variable } = (\text{TypeOf}(\text{variable}))(\text{variable } \text{op } \text{expr}) variable op = expr ⟺ variable = ( TypeOf ( variable )) ( variable op expr )
This behavior eliminates compiler errors when performing arithmetic on narrow primitive types ( byte , short , char ): short s = 50;
- // s = s + 10; // COMPILE ERROR: s + 10 promotes to int; cannot assign int to short
- s += 10; // Compiles! Automatically treated as s = (short)(s + 10)
- byte b = 127;
- b += 1; // Compiles! Silently overflows to -128 without any warning or error
- Parentheses, the Math API, and Arithmetic Edge Cases
The first official objective names the Math API and parentheses alongside promotion and casting, so expect code that mixes them. Parentheses override the precedence table: 2 + 3 * 4 is 14 , while (2 + 3) * 4 is 20 . Operands are still evaluated left to right inside and outside the parentheses.
Core java.lang.Math methods
Call Result Return type and trap
Math.round(2.5) / Math.round(-2.5) 3 / -2 Rounds half up (toward positive infinity); round(double) returns long , round(float) returns int
- Math.round(-2.6) -3 Ties only matter at exactly .5
- Math.floor(-2.5) / Math.ceil(-2.5) -3.0 / -2.0 Both return double , never int
- Math.abs(Integer.MIN_VALUE) -2147483648 Overflow: the absolute value does not fit in an int
- Math.max(3, 4.0) 4.0 The double overload is chosen, so the result is a double
- Math.max(3, 4L) 4 (a long ) Overloads exist for int , long , float , double
- Math.pow(2, 3) 8.0 Always double ; assigning to int needs a cast
- Math.sqrt(16) / Math.sqrt(-1) 4.0 / NaN No exception for negative input
- Math.random() 0.0 <= x < 1.0 double ; (int) (Math.random() * 6) + 1 simulates a die
Math.addExact(Integer.MAX_VALUE, 1) throws ArithmeticException The *Exact methods detect overflow instead of wrapping
Integer division, remainder, and floating-point surprises System.out.println(7 / 2); // 3 (integer division truncates toward zero)
- System.out.println(-7 / 2); // -3
- System.out.println(-7 % 2); // -1 (the remainder takes the sign of the dividend)
- System.out.println(7 % -2); // 1
- System.out.println(Math.floorDiv(-7, 2)); // -4 (rounds toward negative infinity)
- System.out.println(Math.floorMod(-7, 2)); // 1
- System.out.println(1.0 / 0); // Infinity (no exception for floating point)
- System.out.println(0.0 / 0.0); // NaN
- System.out.println(Double.NaN != Double.NaN); // true: NaN is never equal to itself; use Double.isNaN()
- // System.out.println(7 / 0); // ArithmeticException: / by zero (integer types only)
- char arithmetic and string concatenation order
A char operand is promoted to int , so 'a' + 1 is 98 , while (char) ('a' + 1) is 'b' . The + operator is evaluated left to right: once one operand is a String , every later + is concatenation. Therefore 1 + 2 + "3" is "33" but "1" + 2 + 3 is "123" .