An operator is a special symbol that tells Java to perform a specific action on one or more values (called operands). The combination of operators and operands forms an expression. Every expression evaluates to a single value.
Operands are ingredients (5, 3, "Hello"). Operators are the kitchen tools that do something with them: + is the mixer (combines), - is the knife (subtracts), * is the oven (multiplies). The result is the final dish β the evaluated value of the expression.
Java operators are grouped into 8 categories. We will cover each one in depth.
These perform standard mathematical operations. They work on numeric types (byte, short, int, long, float, double).
int a = 17, b = 5; System.out.println(a + b); // 22 β addition System.out.println(a - b); // 12 β subtraction System.out.println(a * b); // 85 β multiplication System.out.println(a / b); // 3 β INTEGER division (truncated!) System.out.println(a % b); // 2 β modulus (remainder: 17 = 5Γ3 + 2) // Result type follows the "larger" operand type: System.out.println(10 + 3.5); // 13.5 (double β int widened) System.out.println(7 + 3); // 10 (int) System.out.println(7.0 + 3); // 10.0 (double)
Integer Division β The #1 Beginner Trap
When both operands are integers, the division result is also an integer β the decimal part is silently dropped. This surprises nearly every beginner.
// int / int = int (decimal silently dropped) System.out.println(7 / 2); // 3 (NOT 3.5!) System.out.println(1 / 4); // 0 (NOT 0.25!) System.out.println(9 / 10); // 0 (NOT 0.9!) // FIX 1: make one operand a double literal System.out.println(7.0 / 2); // 3.5 β System.out.println(7 / 2.0); // 3.5 β // FIX 2: cast one operand to double int x = 7, y = 2; double result = (double) x / y; // 3.5 β β cast BEFORE dividing double wrong = (double)(x / y); // 3.0 β β divides first, THEN casts!
(double)(x / y) first computes integer division (3), then casts to double (3.0). Still wrong! Always cast BEFORE the division: (double)x / y makes x a double first, forcing double division.
Modulus % β Remainder Operator
The % operator returns the remainder after integer division. It is one of the most useful operators in programming.
System.out.println(17 % 5); // 2 (17 = 5Γ3 + 2) System.out.println(10 % 3); // 1 (10 = 3Γ3 + 1) System.out.println(8 % 4); // 0 (8 = 4Γ2 + 0, exactly divisible) System.out.println(3 % 7); // 3 (3 < 7, so remainder IS 3) // Real-world uses of %: int n = 42; boolean isEven = (n % 2 == 0); // true β even/odd check int lastDigit = n % 10; // 2 β extract last digit int secondLastDigit = (n / 10) % 10; // 4 β extract 2nd last digit // Cycling / wrapping around (e.g., 7 days of week): int day = 9; int dayOfWeek = day % 7; // 2 (day 9 β day 2 in the week cycle) // Negative modulus (Java keeps sign of dividend): System.out.println(-7 % 3); // -1 (not 2!) β sign follows -7 System.out.println(7 % -3); // 1 β sign follows 7
Relational operators compare two values and always return a boolean result β either true or false. They are essential for decision-making (if statements, loops).
int a = 10, b = 20; System.out.println(a == b); // false β equal to (NOTE: == not =) System.out.println(a != b); // true β not equal to System.out.println(a > b); // false β greater than System.out.println(a < b); // true β less than System.out.println(a >= b); // false β greater than or equal System.out.println(a <= b); // true β less than or equal System.out.println(a == 10); // true β a equals 10 // Store result in boolean variable: boolean isAdult = (a >= 18); // false (10 is not >= 18) boolean passed = (a > 5); // true (10 > 5)
= is the assignment operator β it puts a value INTO a variable. == is the equality comparison β it checks if two values are equal and returns boolean. Writing if (x = 5) instead of if (x == 5) causes a compile error in Java (assignment doesn't return boolean). In C/C++ this is a silent bug β in Java, the compiler catches it.
Logical operators combine multiple boolean expressions into a single boolean result. Think of them as the words "AND", "OR", "NOT" in English sentences.
boolean p = true, q = false; // && (AND) β BOTH must be true System.out.println(p && q); // false (true AND false = false) System.out.println(p && p); // true (true AND true = true) // || (OR) β AT LEAST ONE must be true System.out.println(p || q); // true (true OR false = true) System.out.println(q || q); // false (false OR false = false) // ! (NOT) β reverses the boolean System.out.println(!p); // false (!true = false) System.out.println(!q); // true (!false = true) // Real-world combined conditions: int age = 25; double income = 40000; boolean loanEligible = (age >= 18) && (income >= 30000); // true int marks = 75; boolean distinction = (marks >= 80) || (marks == 75); // true (second part) boolean notPassed = !(marks >= 50); // false (marks IS >= 50)
Truth Tables
| A | B | A && B |
|---|---|---|
| T | T | T |
| T | F | F |
| F | T | F |
| F | F | F |
| A | B | A || B |
|---|---|---|
| T | T | T |
| T | F | T |
| F | T | T |
| F | F | F |
| A | !A |
|---|---|
| T | F |
| F | T |
Short-Circuit Evaluation β Critical Concept
Java's && and || use short-circuit evaluation: they stop evaluating as soon as the result is determined. This is not just an optimization β it prevents errors and is tested in exams.
// && SHORT-CIRCUIT: if LEFT is FALSE, RIGHT is NEVER evaluated int n = 0; if (n != 0 && 10/n > 1) { // SAFE! 10/n never runs (n != 0 is false) System.out.println("safe"); } // Without short-circuit: 10/0 would throw ArithmeticException // || SHORT-CIRCUIT: if LEFT is TRUE, RIGHT is NEVER evaluated int x = 5; if (x > 0 || ++x > 0) { // x > 0 is TRUE, so ++x is NEVER executed System.out.println(x); // prints 5, NOT 6! } // Non-short-circuit versions: & and | (evaluate BOTH sides always) if (n != 0 & 10/n > 1) { } // DANGEROUS β evaluates both, throws exception
false && anythingβ always false. Right side never evaluated.true || anythingβ always true. Right side never evaluated.- Use
&and|(no double) only when you need both sides evaluated (rare). - Place cheaper/safer conditions on the LEFT side of
&&/||.
The simple = assigns a value. Compound assignment operators combine a math operation with assignment β they are shorthand that makes code cleaner.
int x = 10; // simple assignment: x = 10 // Compound assignment operators: x += 5; // x = x + 5 β x = 15 x -= 3; // x = x - 3 β x = 12 x *= 2; // x = x * 2 β x = 24 x /= 4; // x = x / 4 β x = 6 x %= 4; // x = x % 4 β x = 2 // Also works for strings: String s = "Hello"; s += " World"; // s = "Hello World" // Chained assignment (right to left): int a, b, c; a = b = c = 5; // c=5 first, then b=5, then a=5 β all equal 5 // Compound with implicit narrowing cast: byte byt = 10; byt += 5; // β implicit cast: equivalent to byt = (byte)(byt + 5) // byt = byt + 5 would cause error (int result, needs explicit cast)
byte b = 10; b += 5; works even though b + 5 produces an int. The += operator automatically includes a narrowing cast back to byte. This is different from b = b + 5 which would give a compile error without an explicit cast.
Unary operators work on a single operand. The most important ones are the increment and decrement operators β they are among the most heavily tested in Java exams.
int x = 5; // Unary plus and minus: int pos = +x; // +5 β no change (unary plus rarely used) int neg = -x; // -5 β negates the value // Logical NOT: boolean t = true; boolean f = !t; // false
Increment & Decrement β The Most Tested Operators
Pre-increment ++x: increment FIRST, then use the NEW value.
Post-increment x++: use the OLD value FIRST, then increment.
Both result in x being incremented β the difference is only what value is used in the expression at that moment.
// Standalone β pre and post produce IDENTICAL results: int a = 5; a++; // a = 6 (post-increment standalone) ++a; // a = 7 (pre-increment standalone) a--; // a = 6 (post-decrement) --a; // a = 5 (pre-decrement) // In an expression β CRITICAL DIFFERENCE: int x = 5; int y = x++; // POST: y gets old value (5), then x increments β y=5, x=6 int p = 5; int q = ++p; // PRE: p increments first (6), then q gets new value β q=6, p=6 // Tricky example frequently in exams: int a2 = 5; System.out.println(a2++); // prints 5 (old value), then a2 becomes 6 System.out.println(a2); // prints 6 System.out.println(++a2); // a2 becomes 7 first, then prints 7 System.out.println(a2); // prints 7 // Complex expression (exam trap!): int n = 5; int result = n++ + ++n; // Step 1: n++ uses 5 (old n), n becomes 6 // Step 2: ++n increments 6 to 7, uses 7 // result = 5 + 7 = 12, n = 7
| Code | n before | Expression value | n after |
|---|---|---|---|
int n=5; int y=n++; | 5 | y = 5 (old n) | n = 6 |
int n=5; int y=++n; | 5 | y = 6 (new n) | n = 6 |
int n=5; int y=n--; | 5 | y = 5 (old n) | n = 4 |
int n=5; int y=--n; | 5 | y = 4 (new n) | n = 4 |
int n=5; println(n++); | 5 | prints 5 | n = 6 |
int n=5; println(++n); | 5 | prints 6 | n = 6 |
Bitwise operators work directly on the binary (bit-level) representation of integers. Important for exams and low-level programming.
| Operator | Name | Action | Example | Result |
|---|---|---|---|---|
& | Bitwise AND | 1 only if both bits are 1 | 5 & 3 | 1 (0101 & 0011 = 0001) |
| | Bitwise OR | 1 if at least one bit is 1 | 5 | 3 | 7 (0101 | 0011 = 0111) |
^ | Bitwise XOR | 1 if bits are different | 5 ^ 3 | 6 (0101 ^ 0011 = 0110) |
~ | Bitwise NOT | Flips all bits | ~5 | -6 |
<< | Left Shift | Shift bits left (Γ2 per shift) | 5 << 1 | 10 |
>> | Right Shift | Shift bits right (Γ·2 per shift) | 10 >> 1 | 5 |
>>> | Unsigned Right Shift | Shifts without sign extension | -1 >>> 1 | Integer.MAX_VALUE |
// 5 = 0101, 3 = 0011 System.out.println(5 & 3); // 1 (0101 & 0011 = 0001) System.out.println(5 | 3); // 7 (0101 | 0011 = 0111) System.out.println(5 ^ 3); // 6 (0101 ^ 0011 = 0110) System.out.println(~5); // -6 (flip all bits of 5) // Bit shifting (fast multiply/divide by powers of 2): System.out.println(5 << 1); // 10 (5 Γ 2ΒΉ) System.out.println(5 << 2); // 20 (5 Γ 2Β²) System.out.println(20 >> 2); // 5 (20 Γ· 2Β²) // Practical use: check if number is even (fast even/odd): int n = 42; boolean isEven = (n & 1) == 0; // true β faster than n%2==0
The ternary operator is Java's shorthand for a simple if-else. It is the only three-operand operator in Java. Syntax: condition ? valueIfTrue : valueIfFalse
// Basic ternary: int a = 10, b = 20; int max = (a > b) ? a : b; // max = 20 int min = (a < b) ? a : b; // min = 10 String result = (a % 2 == 0) ? "Even" : "Odd"; // "Even" // Equivalent if-else: int max2; if (a > b) { max2 = a; } else { max2 = b; } // Ternary inside println: System.out.println("Pass or Fail: " + (a > 50 ? "Pass" : "Fail")); // Nested ternary (use sparingly β hurts readability): int score = 75; String grade = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "F"; System.out.println(grade); // "C" // Max of three numbers using nested ternary: int x = 5, y = 9, z = 3; int maxThree = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z); // maxThree = 9
The + operator is overloaded in Java β it means addition for numbers AND concatenation (joining) for Strings. The rules for mixed expressions are a favourite exam topic.
// String + anything = String (left to right evaluation) System.out.println("Hello" + " World"); // "Hello World" System.out.println("Age: " + 20); // "Age: 20" (intβString) System.out.println("Pi: " + 3.14); // "Pi: 3.14" // TRICKY: + is evaluated LEFT TO RIGHT System.out.println(1 + 2 + "3"); // "33" (1+2=3, then "3"+"3"="33") System.out.println("1" + 2 + 3); // "123" ("1"+2="12", "12"+3="123") System.out.println(1 + 2 + 3); // 6 (all ints: 1+2+3=6) // Use () to force desired evaluation order: System.out.println("Sum: " + (1 + 2 + 3)); // "Sum: 6" (brackets first) // Char concatenation β VERY tricky: System.out.println('A' + 'B'); // 131 (char + char = int! 65+66) System.out.println("" + 'A' + 'B'); // "AB" (empty String forces concatenation)
When an expression has multiple operators, Java uses operator precedence to determine which operations to perform first β exactly like BODMAS/PEMDAS in mathematics. Higher precedence = evaluated first.
Precedence Examples β Step by Step
// Example 1: int r = 2 + 3 * 4 - 8 / 2; // Step 1: * and / (same level, left to right): 3*4=12, 8/2=4 // Step 2: + and - (left to right): 2+12=14, 14-4=10 // r = 10 // Example 2: boolean b = 5 + 3 > 6 && 10 - 4 == 6; // Step 1: + and -: 5+3=8, 10-4=6 // Step 2: > and ==: 8>6 is true, 6==6 is true // Step 3: &&: true && true = true // b = true // Example 3: int x = 5; int r2 = x++ * 2 + ++x; // Step 1: x++ uses 5 (post), x becomes 6 // Step 2: 5 * 2 = 10 // Step 3: ++x increments 6 to 7, uses 7 // Step 4: 10 + 7 = 17 // r2 = 17, x = 7 // Example 4 β mixing + and String: System.out.println(2 + 3 + " apples"); // "5 apples" System.out.println("apples: " + 2 + 3); // "apples: 23" (NOT "apples: 5"!) System.out.println("sum: " + (2+3)); // "sum: 5" (brackets force addition first)
Don't rely on memorizing all 14 precedence levels. When you're unsure, just use parentheses () to make the intended order explicit. This also makes your code more readable. (a + b) * (c - d) is clearer than relying on precedence.
- = instead of == β Assignment vs comparison.
if (x = 5)is an error in Java (compile error). Always use==to compare. - Integer division β
7/2gives 3, not 3.5. Cast to double first:(double)7/2. - Post vs pre increment in expressions β
y = x++gives old x.y = ++xgives new x. Know the difference cold. - Short-circuit side effects β
x > 0 || ++count > 0β if x>0, ++count never runs. Avoid side effects in short-circuit expressions. - String + int confusion β
"Value: " + 1 + 2gives "Value: 12". Use"Value: " + (1+2)for "Value: 3". - char arithmetic becomes int β
'A' + 1gives 66, not 'B'. Cast back:(char)('A' + 1). - Negative modulus β
-7 % 3gives -1 in Java, not 2. The sign follows the dividend. - Cast placement for division β
(double)(x/y)β(double)x/y. First casts after integer division; second forces double division.
Program 1:
int a = 5, b = 5; int c = a++ + ++b; System.out.println(a + " " + b + " " + c);
Trace: a++ uses old a(5), then a becomes 6. ++b increments b to 6 first, uses 6. c = 5 + 6 = 11. Final: a=6, b=6, c=11.
Program 2:
System.out.println(10 + 20 + "30"); System.out.println("10" + 20 + 30); System.out.println(10 + (20 + "30"));
102030
12030
Trace 1: 10+20=30 (both ints), then "30"+"30"="3030". Trace 2: "10"+20="1020", "1020"+30="102030". Trace 3: inside brackets: 20+"30"="2030". Then: 10+"2030"="102030" β wait, no. 10 is int, "2030" is String. 10+"2030"="102030". Actually: 10+("2030") = "10"+"2030" = "102030". Let me recheck: 10 + "2030" β int + String = String: "102030". Yes.
Program 3:
int x = 10; boolean r = (x > 5) || (++x > 0); System.out.println(x + " " + r);
Short-circuit: (x > 5) = (10 > 5) = true. Since left side of || is true, the right side (++x > 0) is NEVER evaluated. So x remains 10, not 11. r = true.
- Precedence mnemonic: "Unary Makes Additions Seem Ridiculously Easy And Logical" β Unary, Multiplicative, Additive, Shift, Relational, Equality, And (bitwise), Logical
- Short-circuit: "&& stops at first FALSE. || stops at first TRUE." β like a security guard: && checks everyone (strict), || lets first good one in (lenient).
- Post vs pre: "POST = pay AFTER. PRE = pay BEFORE." Post-increment: use first, pay (increment) later. Pre-increment: pay first, use after.
- Integer division: "Two integers fighting for division lose the decimal in the battle." Cast to double to save it.
- String + int: "If String is at the party, everything becomes a String." Once Java sees a String, + means concatenation.
Q: What is short-circuit evaluation in Java? Explain with an example showing why it is useful.
Answer: Short-circuit evaluation means that in a logical expression with && or ||, the second operand is only evaluated if necessary. For &&: if the first operand is false, the result is always false regardless of the second β so Java skips evaluating the second. For ||: if the first operand is true, the result is always true β so the second is skipped. Example: if (n != 0 && 10/n > 1) β if n is 0, the second condition (10/n) is never evaluated, preventing a division-by-zero ArithmeticException. This makes short-circuit evaluation both a performance optimization AND a safety mechanism.
Q: What is the output of the following? Show step-by-step working.
int a = 5; System.out.println(a++); System.out.println(++a); System.out.println(a-- + --a); System.out.println(a);
Line 1: a++ β prints old a (5), then a becomes 6.
Line 2: ++a β increments a from 6 to 7, prints 7. a=7.
Line 3: a-- β uses old a (7) in expression, then a becomes 6. --a β decrements a from 6 to 5, uses 5. Expression: 7 + 5 = 12. a=5.
Line 4: prints a = 5.
MCQ Bank
System.out.println(7 / 2);int x=5; System.out.println(x++ + " " + ++x);-7 % 3 in Java?int x=5; boolean r = (x > 10) && (++x > 0); What is x after this statement?System.out.println("a" + 1 + 2);a ? b : a > b(a > b) ? a : ba > b ? b : a(a < b) ? a : bSystem.out.println(5 & 3);(double)x/y.condition ? trueValue : falseValue β compact if-else. Returns a value.Easy
int a=3,b=4; int result=a++ + ++b + a; Verify by running.Medium
3 + 4 * 2 - 8 / 4 % 3 + 1. Show every step using operator precedence rules. Then verify.Hard
int a=1; int b=a++ + a++ + ++a; System.out.println(a+" "+b); Trace every step. Then verify.True operator mastery β no IDE, no hints.
- Write from memory: the complete operator precedence table (14 levels) without looking.
- Trace without running:
int x=5; int y = x++ * 2 + ++x - x-- + --x; println(x+" "+y); - Research: What is the difference between
&&and&? When would you intentionally use&instead of&&? Write a practical example. - Challenge: Using ONLY bitwise operators (no +, -, *, /), add two integers. Research "bitwise addition" and implement it.