Study guide
3.1 Arithmetic, Relational, and Logical Operators
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.1 Arithmetic, Relational, and Logical Operators
Key Takeaways Explain This Topic AI
Binary arithmetic operators (+, -, *, /, %) perform binary numeric promotion, widening operands narrower than int to int, or promoting to the widest operand type (long, float, double).
Integer division truncates towards zero by dropping any fractional decimal remainder; dividing or taking modulus by integer zero throws an unchecked ArithmeticException at runtime.
Floating-point division and modulus operations conform to IEEE 754 standards, returning Infinity, -Infinity, or NaN without throwing an ArithmeticException.
The modulus operator (%) calculates remainder using the formal formula a - (a / b) * b, meaning the resulting sign strictly matches the dividend (left operand) while the divisor's sign is ignored.
Short-circuit logical operators (&&, ||) skip evaluation of the right operand when the left operand determines the overall truth value, preventing runtime errors such as NullPointerException and division by zero.
Last updated: September 2026
3.1 Arithmetic, Relational, and Logical Operators
Note
Exam Focus : Two of Oracle's 13 published topic areas land here — "Working with Java Operator" (six objectives, the largest single topic on the outline) and part of "Using Decision Statements". Oracle publishes no percentage weightings for 1Z0-811, but by raw objective count this is the densest region of the syllabus. Candidates are rigorously tested on binary numeric promotion, integer division truncation versus floating-point division producing special IEEE 754 values, the modulus sign rule with negative operands, primitive equality versus object reference comparison, and short-circuit logical evaluation side effects.
In Java, operators are special symbols or keywords that direct the Java Virtual Machine (JVM) to perform specific mathematical, relational, or logical calculations on one, two, or three data values. The values or expressions operated upon are termed operands . Java strictly classifies operators based on the number of operands they require:
Unary Operators: Operate on a single operand (e.g., ++count , -delta , !isValid , ~bitmask ).
Binary Operators: Operate on two operands positioned on either side in infix notation (e.g., a + b , x * y , p && q ).
Ternary Operator: Operates on three operands, providing an inline conditional expression ( condition ? exprTrue : exprFalse ).
Every operator expression produces a concrete resulting value possessing an exact data type dictated by the operator and the types of its evaluated operands.
1. Binary Arithmetic Operators & Binary Numeric Promotion
Java provides five fundamental binary arithmetic operators for numeric computation:
- Operator Mathematical Operation Example Expression Evaluated Result
- + Addition (or String Concatenation) 14 + 5 19
- Subtraction 14 - 5 9
- * Multiplication 14 * 5 70
- / Division (Integer or Floating-Point) 14 / 5 2 (integer) or 2.8 (double)
- % Modulus (Remainder after division) 14 % 5 4
- Binary Numeric Promotion Rules (JLS §5.6.2)
Whenever a binary arithmetic operator is applied to numeric operands, the JVM applies binary numeric promotion prior to calculation. The operands are widened according to these four sequential rules:
If either operand is double , the other operand is widened to double , and the operation yields a double .
Otherwise, if either operand is float , the other operand is widened to float , and the operation yields a float .
Otherwise, if either operand is long , the other operand is widened to long , and the operation yields a long .
- Otherwise, both operands are promoted to int , and the operation yields a 32-bit int . byte b1 = 10;
- byte b2 = 20;
- // byte b3 = b1 + b2; // COMPILE ERROR: incompatible types: possible lossy conversion from int to byte
- int sum = b1 + b2; // Compiles cleanly: b1 and b2 are promoted to int before addition
- byte b3 = (byte)(b1 + b2); // Compiles cleanly with an explicit narrowing cast
Warning
The Narrow Integer Promotion Trap : Arithmetic on byte , short , or char always promotes operands to int . Even if you add two short primitives ( short s = 1 + 2; ), literal addition is constant-folded, but variable addition ( short s3 = s1 + s2; ) fails compilation without an explicit cast back to short .
2. Integer Division vs. IEEE 754 Floating-Point Division
The division operator ( / ) behaves fundamentally differently depending on whether its operands are integer types or floating-point types.
Integer Division: Truncation Toward Zero
When both operands are integral types ( byte , short , char , int , long ), Java performs integer division . In integer division, the result is strictly an integer. The JVM discards any fractional decimal part without rounding toward the nearest integer—it always truncates toward zero : int res1 = 15 / 4; // Evaluates to 3 (15 / 4 = 3.75 -> truncated to 3)
- int res2 = 3 / 4; // Evaluates to 0 (3 / 4 = 0.75 -> truncated to 0)
- int res3 = -15 / 4; // Evaluates to -3 (-3.75 truncated toward zero -> -3)
- Integer Division by Zero: ArithmeticException
Attempting to divide an integer by literal 0 or an integer variable holding 0 compiles cleanly (because 0 is a valid integer literal), but the JVM halts execution at runtime and throws an unchecked java.lang.ArithmeticException: / by zero : int numerator = 100;
- int denominator = 0;
- int outcome = numerator / denominator; // Throws java.lang.ArithmeticException at runtime
- Floating-Point Division: IEEE 754 Special Values
If at least one operand is a floating-point type ( float or double ), Java executes floating-point division conforming to the IEEE 754 standard. Truncation does not take place, and an ArithmeticException is never thrown :
Positive Non-Zero divided by 0.0 : Produces positive infinity ( Double.POSITIVE_INFINITY , printed as Infinity ).
Negative Non-Zero divided by 0.0 : Produces negative infinity ( Double.NEGATIVE_INFINITY , printed as -Infinity ).
Zero divided by 0.0 : Produces Not-a-Number ( Double.NaN , printed as NaN ). double d1 = 15.0 / 4; // 3.75 (4 promoted to 4.0)
- double d2 = 15 / 4; // 3.0 (Integer division 15 / 4 yields 3, which widens to 3.0!)
- double d3 = (double)15 / 4; // 3.75 (15 cast to 15.0 prior to division)
- double posInf = 25.0 / 0.0; // Infinity (no exception)
- double negInf = -25.0 / 0.0; // -Infinity (no exception)
- double notANum = 0.0 / 0.0; // NaN (no exception)
Expression Operand Types Evaluated Value Throws Exception?
- 9 / 2 int / int 4 No
- 9 / 2.0 int / double 4.5 No
- (double)(9 / 2) (double)(int) 4.0 No (integer division evaluates first)
- (double)9 / 2 double / int 4.5 No (9 cast to 9.0 first)
- 10 / 0 int / int None Yes: ArithmeticException
- 10.0 / 0 double / int Infinity No
- 10.0 / 0.0 double / double -Infinity No
- 0.0 / 0.0 double / double NaN No
- 3. The Modulus (Remainder) Operator ( % )
The modulus operator ( % ) calculates the remainder resulting from dividing the left operand (dividend) by the right operand (divisor).
Mathematical Definition in the Java Language Specification (JLS §15.17.3)
In Java, the modulus operator is strictly defined by the formula: a % b = a − ( a / b ) ∗ b a \% b = a - (a / b) * b a % b = a − ( a / b ) ∗ b
Because integer division a / b truncates toward zero, the sign of the remainder is entirely determined by the dividend a .
The Golden Dividend Sign Rule
On the 1Z0-811 examination, questions testing the modulus operator frequently present combinations of positive and negative numbers. Memorize this absolute rule:
The algebraic sign of the result of a modulus operation strictly matches the sign of the left operand (the dividend). The sign of the right operand (the divisor) is completely ignored! System.out.println( 19 % 5); // 4 (Dividend +19 is positive -> +4)
- System.out.println(-19 % 5); // -4 (Dividend -19 is negative -> -4)
- System.out.println( 19 % -5); // 4 (Dividend +19 is positive -> +4; divisor sign ignored)
- System.out.println(-19 % -5); // -4 (Dividend -19 is negative -> -4; divisor sign ignored)
Let us trace -19 % -5 using the official JLS formula:
-19 / -5 = 3 (negative divided by negative is positive 3; truncation preserves 3).
3 * (-5) = -15 .
-19 - (-15) = -19 + 15 = -4 .
Notice that despite both operands being negative, the modulus result is -4 , strictly preserving the negative sign of the dividend.
Floating-Point Modulus
Unlike C and C++ where % requires integer operands, Java permits modulus operations on float and double : double rem = 7.5 % 2.0; // 1.5 (7.5 - (3 * 2.0) = 1.5)
double zeroRem = 5.5 % 0.0; // Double.NaN (no exception!)
Taking integer modulus by zero ( 10 % 0 ) throws an ArithmeticException , whereas floating-point modulus by zero ( 10.0 % 0.0 ) produces NaN .
4. String Concatenation Operator ( + )
The plus symbol ( + ) is the only operator in Java that is overloaded by the language specification. If either operand in a binary addition expression is a String object, Java treats + as the String Concatenation Operator rather than arithmetic addition.
Left-to-Right Evaluation and Precedence
Because binary + associates from left to right, the order of numeric and string operands dictates the outcome: System.out.println(1 + 2 + "3"); // Prints "33" (1 + 2 = 3; 3 + "3" = "33")
- System.out.println("1" + 2 + 3); // Prints "123" ("1" + 2 = "12"; "12" + 3 = "123")
- System.out.println("Result: " + (1 + 2)); // Prints "Result: 3" (parentheses evaluate first)
When a primitive value is concatenated with a string, the primitive is converted to its string representation (e.g., true becomes "true" , 5 becomes "5" ). If an object reference is concatenated, its toString() method is invoked; if the reference is null , the literal four-character text "null" is appended.
5. Relational Comparison Operators
Java provides four relational operators that test order comparisons between two operands:
- < : Less than
- <= : Less than or equal to
- > : Greater than
- >= : Greater than or equal to
- Strict Rules for Relational Operators
Always Return Primitive boolean : Every relational comparison evaluates strictly to true or false .
Numeric Operands Only : Relational operators can only be applied to numeric primitive types ( byte , short , char , int , long , float , double ).
No Boolean or Reference Comparison : Applying < , <= , > , or >= to boolean variables, strings, or object references causes a compile-time error: int age = 21;
boolean canVote = age >= 18; // Valid: true
- char letter = 'B'; // Unicode 66
- boolean isAfterA = letter > 'A'; // Valid: 66 > 65 evaluates to true
- // COMPILE ERRORS: bad operand types for binary operator '>'
- // boolean bad1 = true > false;
- // boolean bad2 = "Apple" < "Banana";
When comparing operands of different numeric types, binary numeric promotion widens the narrower operand before evaluating the comparison: System.out.println(10.0 > 10); // false (int 10 promoted to double 10.0; 10.0 > 10.0 is false)
- System.out.println(10.0 >= 10); // true (10.0 >= 10.0 is true)
- 6. Equality Operators: Value Equality vs. Reference Identity
Java provides two equality operators: equal-to ( == ) and not-equal-to ( != ). Their evaluation behavior depends fundamentally on whether they compare primitives or object references.
1. Primitive Equality: Value Comparison
When applied to primitive data types, == compares the raw binary values stored in memory. Operands of different numeric types undergo binary numeric promotion before comparison: int x = 25;
- double y = 25.0;
- System.out.println(x == y); // true (x is widened to double 25.0; 25.0 == 25.0 is true)
- char ch = 'A'; // Unicode 65
- System.out.println(ch == 65); // true (ch is promoted to int 65; 65 == 65 is true)
- boolean b1 = true;
- boolean b2 = false;
- System.out.println(b1 == b2); // false (compares boolean truth values)
- 2. Reference Equality: Memory Address Comparison
When applied to object reference variables (such as String , arrays, and class instances), == tests reference identity —whether both reference variables point to the exact same memory address on the Java Heap : String s1 = new String("Java");
- String s2 = new String("Java");
- String s3 = s1;
- System.out.println(s1 == s2); // false (distinct heap objects at different memory addresses)
- System.out.println(s1 == s3); // true (both variables hold the identical heap reference pointer)
- System.out.println(s1.equals(s2)); // true (compares character sequence contents)
Important
Exam Trap: == vs .equals() : Never use == to compare text contents of strings. The == operator verifies whether two references point to the same memory location, while .equals() inspects the underlying character values.
7. Unconditional vs. Short-Circuit Logical Operators
Java supports two distinct sets of logical operators for evaluating boolean expressions:
- Unconditional Operators: & (Logical AND), | (Logical OR), ^ (Logical XOR), ! (Logical Complement)
- Short-Circuit Operators: && (Conditional AND), || (Conditional OR)
- Truth Table for Boolean Operators
- p q p & q / p && q p | q / p || q p ^ q (XOR) !p (NOT)
- true true true true false false
- true false false true true false
- false true false true true true
- false false false false false true
- Unconditional Logical Operators ( & , | )
The single ampersand & and single pipe | are unconditional operators. When evaluating left & right or left | right , both operands are always evaluated , even when the left operand has already determined the final truth value of the expression: int count = 0;
- boolean flag = (5 > 10) & (++count > 0); // 5 > 10 is false, but ++count is STILL evaluated
- System.out.println("flag=" + flag + ", count=" + count); // flag=false, count=1
- Short-Circuit Logical Operators ( && , || )
Short-circuit operators optimize performance and provide safety by bypassing evaluation of the right-hand operand whenever the left-hand operand decisively establishes the outcome:
Short-Circuit AND ( && ) : If the left operand evaluates to false , the overall expression can never be true . The right operand is completely skipped .
Short-Circuit OR ( || ) : If the left operand evaluates to true , the overall expression is guaranteed to be true . The right operand is completely skipped . int score = 0;
boolean check = (5 > 10) && (++score > 0); // 5 > 10 is false -> ++score is SKIPPED!
- System.out.println("check=" + check + ", score=" + score); // check=false, score=0
- The Null Safety Guard Idiom
The most vital real-world and examination application of short-circuit evaluation is the null safety guard . By testing for null on the left of && , safe code prevents fatal NullPointerException crashes: String text = null;
// SAFE: Short-circuits when text == null; text.length() is NEVER invoked!
- if (text != null && text.length() > 0) {
- System.out.println("Valid text");
- }
// FATAL RUNTIME ERROR: Unconditional & evaluates both sides, crashing with NullPointerException!
// if (text != null & text.length() > 0) { ... }
Similarly, short-circuit operators safeguard against ArrayIndexOutOfBoundsException when validating indices before accessing array slots: int[] data = { 10, 20, 30 };
- int idx = 3;
- if (idx >= 0 && idx < data.length && data[idx] > 0) {
- System.out.println("Positive element");
- }
// Safe: idx < data.length is false (3 < 3 is false), data[3] is never evaluated!