Study guide
3.2 Unary Operators, Assignment, and Operator Precedence
Oracle Certified Foundations Associate, Java 1Z0-811
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1Z0-811 Exam Overview & Certification Path Setting Up the JDK 8 Environment & Recommended Study Plan
2 Chapter 1: Java Basics & Program Architecture
1.1 What Is Java & Core Platform Features 1.2 The Java Runtime Architecture & Memory Management 1.3 Structure of a Java Program & The main Method 1.4 Compiling, Running, and Package Management
3 Chapter 2: Working with Data Types & Strings
2.1 The Eight Primitive Data Types & Literal Values 2.2 Type Conversion, Casting, and Numeric Promotion 2.3 The String Class, Immutability, and the String Constant Pool 2.4 String Methods, StringBuilder Operations, and Type Parsing
4 Chapter 3: Operators & Decision Statements
3.1 Arithmetic, Relational, and Logical Operators 3.2 Unary Operators, Assignment, and Operator Precedence 3.3 Decision Making: if, if-else, and the Ternary Operator 3.4 The switch Statement & Multi-Way Branching
5 Chapter 4: Working with Java Arrays and ArrayLists
4.1 Array Declaration, Instantiation, and Initialization 4.2 Array Indexing, Bounds Checking, and Iteration Mechanics 4.3 Two-Dimensional and Ragged Arrays 4.4 ArrayList Fundamentals, Operations, and Array Comparison
6 Chapter 5: Using Looping Statements
5.1 While and Do-While Loops 5.2 Standard for Loops & Control Flow 5.3 The Enhanced For-Each Loop 5.4 Branching with Break and Continue
7 Chapter 6: Working with Methods
6.1 Method Declaration, Parameters, and Return Types 6.2 Argument Passing: Pass-by-Value Mechanics 6.3 Method Overloading Principles 6.4 Static vs. Instance Methods and Variable Scoping Rules
8 Chapter 7: Classes, Objects, and Constructors
7.1 Defining Classes and Instantiating Objects 7.2 Constructor Rules and Overloading 7.3 The this Reference and Constructor Chaining
9 Chapter 8: Encapsulation, Inheritance, and Members
8.1 Encapsulation and Access Modifiers 8.2 Inheritance Fundamentals and the super Keyword 8.3 Method Overriding and Polymorphic Method Execution
10 Chapter 9: Debugging, Documentation, and Exceptions
9.1 Syntax Errors, Runtime Errors, and Logic Errors 9.2 Documentation with Javadoc & Core Utilities 9.3 Exception Hierarchy & Defensive try-catch 9.4 The finally Block & Common Runtime Exceptions
3.2 Unary Operators, Assignment, and Operator Precedence
Key Takeaways Explain This Topic AI
Unary operators act upon a single operand; unary plus (+) and minus (-) apply unary numeric promotion (widening byte, short, char to int), while logical complement (!) negates booleans and bitwise inversion (~) inverts bits according to ~x = -(x + 1).
Prefix increment and decrement (++x, --x) update the variable in memory before returning the new value to the containing expression, whereas postfix operators (x++, x--) return the original value before updating memory.
In expressions with side effects, Java evaluates operands strictly from left to right; the classic self-assignment trap x = x++ restores the original value of x, completely discarding the increment.
Compound assignment operators (+=, -=, *=, /=, %=) automatically inject an implicit narrowing cast E1 = (T)((E1) op (E2)), enabling arithmetic on byte, short, and char without compilation errors but risking silent numeric overflow.
Operator precedence establishes the syntactic binding of operands, with postfix operators having highest precedence, followed by unary, multiplicative, additive, relational, equality, logical, ternary, and assignment operators.
Last updated: September 2026
3.2 Unary Operators, Assignment, and Operator Precedence
Note
Exam Focus : The 1Z0-811 examination frequently tests candidate mastery of complex expressions containing prefix and postfix increment/decrement operators, chained assignments, compound assignments on narrow integer types ( byte , short ), and operator precedence. Candidates must be able to trace operand evaluation from left to right and account for state changes at each execution step.
Java operators are distinguished not only by their mathematical purpose but by their arity (number of operands), precedence (order of binding), and associativity (direction of evaluation among operators of equal rank). Understanding unary operators, assignment expressions, and operator binding rules is critical for accurately predicting program output on the certification exam.
1. Unary Operators: + , - , ! , ~
Unary operators operate on a single operand. Java defines four primary non-increment unary operators:
Unary Plus ( + ) and Unary Minus ( - )
Unary Plus ( + ): Explicitly denotes a positive numeric value (rarely needed). Crucially, like binary arithmetic, unary plus applies unary numeric promotion (JLS §5.6.1), automatically promoting any operand narrower than int ( byte , short , char ) to 32-bit int .
Unary Minus ( - ): Negates the arithmetic sign of its operand, also promoting narrow integer operands to int . byte b = 15;
// byte negB = -b; // COMPILE ERROR: -b promotes b to int; cannot assign int to byte!
- int negB = -b; // Compiles cleanly: result is -15
- byte castNeg = (byte)-b; // Compiles cleanly with explicit narrowing cast
- Logical Complement ( ! )
The logical NOT operator ( ! ) inverts the value of a boolean expression: !true evaluates to false , and !false evaluates to true . It operates strictly on boolean operands; applying ! to numeric types causes an immediate compilation failure. boolean loggedIn = false;
- boolean showLoginPrompt = !loggedIn; // Evaluates to true
- Bitwise Inversion / Complement ( ~ )
The bitwise complement operator ( ~ ) inverts every bit in an integral value's two's-complement binary representation (converting 0 bits to 1 , and 1 bits to 0 ). The mathematical formula for bitwise inversion on any integer x x x is: ∼ x = − ( x + 1 ) \sim x = -(x + 1) ∼ x = − ( x + 1 ) int val = 7;
- System.out.println(~val); // Outputs -8 (-(7 + 1))
- int zero = 0;
- System.out.println(~zero); // Outputs -1 (-(0 + 1))
- int neg = -10;
- System.out.println(~neg); // Outputs 9 (-(-10 + 1))
Like unary minus, the ~ operator applies unary numeric promotion, promoting byte , short , and char operands to int .
2. Prefix vs. Postfix Increment and Decrement Operators
The increment ( ++ ) and decrement ( -- ) operators increase or decrease a variable's value by exactly 1 . x++; // Semantically equivalent to: x = x + 1;
x--; // Semantically equivalent to: x = x - 1;
Warning
Variables Only : Increment and decrement operators can only be applied to variables. Applying them to numeric literals, constants, or parenthesized expressions causes a compile-time error ( unexpected type: required variable, found value ): // 10++; // COMPILE ERROR: 10 is a literal, not a variable
- // (x + 1)++; // COMPILE ERROR: (x + 1) is a value expression
- Prefix Operators ( ++x , --x )
In prefix position, the operator precedes the variable. The variable in memory is modified first , and the new, updated value is returned to the containing expression: int x = 5;
- int y = ++x; // Step 1: x increments from 5 to 6 in memory; Step 2: y is assigned the new value 6
- System.out.println("x=" + x + ", y=" + y); // Prints: x=6, y=6
- Postfix Operators ( x++ , x-- )
In postfix position, the operator follows the variable. The variable's original, current value is captured and returned to the containing expression first; afterward , the variable is modified in memory: int x = 5;
- int y = x++; // Step 1: y is assigned the original value 5; Step 2: x increments from 5 to 6 in memory
- System.out.println("x=" + x + ", y=" + y); // Prints: x=6, y=5
- Operator Syntax Name Timing of Memory Mutation Value Returned to Expression
- ++x Prefix Prefix Increment Increments x x x by 1 before reading value The new incremented value
- x++ Postfix Postfix Increment Increments x x x by 1 after reading value The original unincremented value
- -x Prefix Prefix Decrement Decrements x x x by 1 before reading value The new decremented value
- x-- Postfix Postfix Decrement Decrements x x x by 1 after reading value The original undecremented value
- 3. Dissecting Complex Expressions with Side Effects
On Exam 1Z0-811, you will encounter complex expressions combining prefix and postfix operators across one or more variables. To solve these reliably, always follow this rule from JLS §15.7:
In Java, operands of an operator are strictly evaluated from left to right.
- Case Study 1: Mixed Prefix and Postfix on a Single Variable int a = 5;
- int b = a++ + ++a;
- System.out.println("a=" + a + ", b=" + b);
Step-by-step trace of a++ + ++a :
Evaluate left operand a++ : Postfix captures the current value 5 . Variable a is then incremented to 6 in memory.
Evaluate right operand ++a : Prefix increments a from 6 to 7 in memory first, then returns 7 .
Perform addition: 5 + 7 = 12 .
Assign to b : b = 12 . Final state: a = 7 , b = 12 .
- Case Study 2: The Notorious Self-Assignment Trap int count = 10;
- count = count++;
- System.out.println(count);
What is printed? Many candidates mistakenly assume 11 . The correct output is 10 !
Here is the exact bytecode execution sequence:
The right-hand expression count++ is evaluated. Because it is postfix, it yields the current value 10 and schedules count for incrementing.
Variable count is incremented in memory to 11 .
The simple assignment operator = executes, storing the yielded value 10 back into variable count .
The 11 in memory is completely overwritten with 10 . The final value of count remains 10 !
- Case Study 3: Multiple Variables in Compound Arithmetic int x = 3;
- int y = 6;
- int z = ++x * y-- - x--;
- System.out.println("x=" + x + ", y=" + y + ", z=" + z);
Trace:
Multiplication ( * ) has higher precedence than subtraction ( - ), but operands evaluate strictly left-to-right:
Left operand of * is ++x : x increments from 3 to 4 , yields 4 .
Right operand of * is y-- : Postfix yields current y value 6 , then decrements y to 5 .
Perform multiplication: 4 * 6 = 24 .
Subtraction operator evaluates its right operand x-- : Postfix yields current x value 4 , then decrements x to 3 .
Perform subtraction: 24 - 4 = 20 .
Assign to z : z = 20 . Final values: x = 3 , y = 5 , z = 20 .
4. Simple Assignment and Chained Assignment
The simple assignment operator ( = ) assigns the value of the right-hand expression to the variable named on the left.
Assignment is an Expression
In Java, an assignment is not merely a statement—it is an expression that returns the value being assigned . Because assignment associates from right to left , you can chain assignments: int a, b, c;
- a = b = c = 100; // Evaluates right-to-left: (a = (b = (c = 100)))
- // All three variables receive 100
- The Boolean Assignment Trap in Conditions
Because assignment returns a value, writing an assignment inside a conditional statement is syntactically legal if the variable is boolean : boolean isClosed = false;
if (isClosed = true) { // Assigns true to isClosed, and the expression evaluates to true!
System.out.println("Store is closed"); // ALWAYS EXECUTES!
}
If the variable is numeric, such as if (x = 5) , the code fails compilation because the expression evaluates to integer 5 , which cannot be converted to boolean .
5. Compound Assignment Operators & The Implicit Cast Rule
Java provides eleven compound assignment operators: += , -= , *= , /= , %= , &= , |= , ^= , <<= , >>= , and >>>= .
A compound assignment operator combines an arithmetic or bitwise operation with assignment: x += 5; // Conceptually related to: x = x + 5;
The Implicit Narrowing Cast Rule (JLS §15.26.2)
There is a critical architectural difference between simple assignment with addition and compound assignment. The Java Language Specification formally defines that a compound assignment of the form: E 1 op = E 2 E_1 \text{ op}= E_2 E 1 op = E 2
is equivalent to: E 1 = ( T ) ( ( E 1 ) op ( E 2 ) ) E_1 = (T)((E_1) \text{ op } (E_2)) E 1 = ( T ) (( E 1 ) op ( E 2 ))
where T T T is the declared data type of variable E 1 E_1 E 1 , with E 1 E_1 E 1 evaluated only once.
This means compound assignment operators automatically insert an implicit narrowing cast back to the type of the left-hand variable! short s = 20;
// s = s + 5; // COMPILE ERROR: s + 5 promotes to int; cannot assign int to short!
s += 5; // COMPILES CLEANLY: Compiler injects (short)(s + 5)
byte b = 50;
// b = b * 2; // COMPILE ERROR: b * 2 produces int!
- b *= 2; // COMPILES CLEANLY: Compiler injects (byte)(b * 2)
- The Silent Numeric Overflow Danger
Because compound assignment operators inject an explicit cast without compiler warning, numeric overflow can occur silently at runtime: byte maxByte = 127;
maxByte += 1; // Evaluates to (byte)(128) -> wraps around to -128 in two's complement!
- System.out.println(maxByte); // Prints: -128 (no error, no exception)
- 6. Comprehensive Operator Precedence & Associativity Hierarchy
When multiple operators appear in a single expression without parentheses, Java's operator precedence determines how operands bind to operators. When two operators share the same precedence level, associativity dictates whether evaluation groups from left to right or from right to left.
- Precedence Level Operator Category Specific Operators Associativity
- 1 (Highest) Postfix expr++ , expr-- Left-to-Right
- 2 Unary Prefix ++expr , --expr , +expr , -expr , ~ , ! Right-to-Left
- 3 Cast / Creation (type) , new Right-to-Left
- 4 Multiplicative * , / , % Left-to-Right
- 5 Additive + , - Left-to-Right
- 6 Shift << , >> , >>> Left-to-Right
- 7 Relational < , <= , > , >= , instanceof Left-to-Right
- 8 Equality == , != Left-to-Right
- 9 Bitwise AND & Left-to-Right
- 10 Bitwise XOR ^ Left-to-Right
- 11 Bitwise OR | Left-to-Right
- 12 Conditional AND && Left-to-Right
- 13 Conditional OR || Left-to-Right
- 14 Ternary Conditional ? : Right-to-Left
- 15 (Lowest) Assignment = , += , -= , *= , /= , %= , etc. Right-to-Left
- Using Parentheses to Override Precedence
Parentheses () possess the highest binding power and can be used to explicitly dictate evaluation order and eliminate ambiguity: int result1 = 5 + 3 * 2; // 5 + 6 = 11 (* takes precedence over +)