The canteen offer
The canteen runs an offer: “If your bill is over ₹70 and you're a member, get a free chai.” Riya writes the bill logic: price × quantity, plus a packing charge, plus 10% tax, then the offer check. Her first version gives free chai to everybody. Arjun Sir looks at one line and smiles.
Sir, I wrote isMember || total > 70 && isStudent and everyone who's a member gets free chai, even with a ₹20 bill!
Because && binds tighter than ||, just like * binds tighter than +. Java read it as isMember || (total > 70 && isStudent). Operators have a ranking called precedence.
So I should add brackets to say exactly what I mean.
Always, when you mix operators. Let's go through every operator family, and watch the order Java follows behind the screen.
What is an operator?
An operator is a symbol that performs an operation on one, two or three operands and produces a result. Java's operators are grouped as arithmetic, unary (including increment/decrement), assignment, relational, logical, bitwise and shift, the ternary conditional operator, and instanceof. When an expression contains several operators, precedence decides which is applied first and associativity decides the order among operators of equal precedence.
Operators are action symbols: + adds, > compares, && joins conditions. Like BODMAS in school maths, Java has rules about which action happens first. Brackets always win.
Words you'll meet in this lesson
a + b, a and b are operands.-x), two (a + b) or three (c ? a : b) operands.* before +; && before ||.&& and || skip the right side when the left side already decides the answer.x++ changing x while also producing a value.All operator families
| Family | Operators | Example → result |
|---|---|---|
| Arithmetic | + - * / % | 17 / 5 → 3 · 17 % 5 → 2 |
| Unary | + - ++ -- ! | -x · count++ · !isPaid |
| Assignment | = += -= *= /= %= … | total += 10 means total = total + 10 |
| Relational | == != < > <= >= | marks >= 40 → true/false |
| Logical | && || ! | age >= 18 && hasId |
| Bitwise | & | ^ ~ | 5 & 3 → 1 · 5 | 3 → 7 · 5 ^ 3 → 6 |
| Shift | << >> >>> | 1 << 10 → 1024 |
| Ternary | ? : | marks >= 40 ? "Pass" : "Fail" |
| Type check | instanceof | obj instanceof String (Module 7) |
Exam tip: the precedence order to remember, highest first: postfix (x++) → unary (++x, !, −) → * / % → + − → shifts → relational (< >) → equality (== !=) → & → ^ → | → && → || → ?: → assignment. When in doubt, use brackets: they make the code clearer for humans too.
The tricky operators, up close
x++ vs ++x
Postfix x++: use the old value, then add 1. Prefix ++x: add 1 first, then use the new value. Alone on a line, both just add 1.
/ and %
Integer / drops the fraction; % gives the remainder. 17 samosas for 5 friends: 17 / 5 = 3 each, 17 % 5 = 2 left. % keeps the sign of the left side: -7 % 3 = −1.
&& and || short-circuit
a && b: if a is false, b is never evaluated. a || b: if a is true, b is skipped. That's why s != null && s.length() > 0 is safe.
Bitwise & | ^ ~
Work on each bit separately. Used for flags and permissions: READ | WRITE combines; perms & WRITE tests. On booleans, & and | evaluate both sides (no short-circuit).
Shift operators
| Operator | Meaning | Example |
|---|---|---|
<< | Shift bits left, fill with 0 (× 2 per step) | 3 << 2 → 12 |
>> | Shift right, keep the sign bit (÷ 2, rounding down) | -7 >> 1 → −4 |
>>> | Shift right, fill with 0 (unsigned shift) | -7 >>> 28 → 15 |
String +: when either operand of + is a String, it means “join”. Evaluation is left to right, so 1 + 2 + "3" + 4 + 5 gives "3345": 1 + 2 = 3 first, then everything after the string is joined.
How Java evaluates an expression
Take total = price * qty + 10 > 70 && member. Java follows the same steps for any expression.
Group by precedence
javac adds invisible brackets:
This happens while parsing. The compiler builds a tree where higher-precedence operators sit lower, closer to the values.total = (((price * qty) + 10) > 70) && member.Evaluate operands left to right
Java always evaluates the left operand of a binary operator before the right one.
Unlike C, this order is guaranteed by the Java specification, soa++ + aalways gives the same result on every JVM.Apply each operator
In bytecode this is a sequence on the operand stack:price * qty→ 60,+ 10→ 70,> 70→ false.iload,iload,imul,bipush 10,iadd, then a comparison and a jump.Short-circuit if possible
The left side of
javac compiles&&is false, somemberis never read.&&into a conditional jump: if the left side is false, jump straight past the right side.Assign the result
The final value goes into
An assignment is itself an expression whose value is the assigned value. That's whytotal. Assignment has the lowest precedence and works right to left:a = b = 5sets b first, then a.if (x = 5)is a type error in Java: the result is an int, not a boolean.
Six operator surprises: both views
Left: the code and what prints. Right: the order of evaluation and the bits.
- Precedence:
3 * 5runs first, so the answer is 35, not 115. a++ + ++agives 12 and leaves a = 7. Two increments, two different moments.17 / 5= 3,17 % 5= 2, and-7 % 3= −1, not 2.- With
&&, the null check fails first, sos.length()never runs. - Bitwise OR combines flags into one number; AND tests a single flag.
- The ternary operator chooses between two values based on a condition.
- javac builds an expression tree:
*sits lower, so it's evaluated first. a++hands over 5 then increments;++aincrements to 7 then hands over 7. The left side always goes first.- Java defines
%so that(a / b) * b + a % b == a. Division rounds towards zero, so the remainder takes the left side's sign. &&is compiled as a jump: when the left side is false, the right side is skipped entirely.- Flags are powers of two.
|sets bits;&tests whether a bit is set. - The ternary operator evaluates the condition, then only the chosen branch.
Operators in real systems
Operators look like school maths, but in production code they do some clever jobs.
Watch it with an example: checkout rules at an online store
Cart total Rs 850, the customer is a member. Watch each operator do its job, in the order Java evaluates them.
- Inputs: cart total is 850 and the customer is a member.
- GST:
*and/have the same precedence, so Java goes left to right: 850 × 18 = 15,300, then ÷ 100 = 153 (integer result). - Comparison:
total >= 500doesn't change anything; it produces aboolean, heretrue. - Logical AND:
big && memberis true only if both are true. Ifbigwere false, Java would not even look atmember(short-circuit). - Ternary:
condition ? a : bpicks a value in one line. 850 is below 999, so delivery costs 40. - Final bill: 850 + 153 − 100 + 40 = 943. Real checkouts use the same operators, just with more rules (and paise instead of rupees).
1. Spreading data across servers
Systems often decide which server or partition stores a record with the remainder operator, like userId % 4. Kafka and many databases use the same idea with hash values.
2. Permissions and feature flags
File permissions (like Linux's read/write/execute) and some feature-flag systems pack many yes/no options into one number, combined with | and tested with &.
3. Safe and fast checks with short-circuiting
Code puts the cheap or null-safe check first: user != null && user.isActive(), or cache.has(key) || loadFromDatabase(key), so the expensive or risky part runs only when needed.
4. Inside Java's own HashMap
HashMap mixes bits of a key's hash with ^ and >>>, then picks a bucket with & (n - 1), a fast replacement for % when n is a power of two (Lesson 11.6).
5. Business rules in checkout
Offers such as “free delivery if the cart is over ₹399 or the user is a member, and the address is serviceable” are logical expressions. Getting the brackets right is the difference between a promotion and a loss.
Examples are simplified to show where operators fit. Real implementations vary.
Riya's canteen bill
public class Main {
public static void main(String[] args) {
int price = 20, qty = 3;
int total = price * qty + 10; // * before +
total += total / 10; // add 10% tax
int a = 5;
int b = a++ + ++a; // 5 + 7
boolean member = total > 70 && a % 2 == 1;
String msg = member ? "Free chai!" : "No offer";
System.out.println(total + " " + a + " " + b + " " + msg);
}
}price * qty + 10Multiplication first: 60 + 10 = 70.total += total / 10;Compound assignment: 70 + 7 = 77 (integer division).a++ + ++aUses 5, then a becomes 6; then a becomes 7 and 7 is used. b = 12.total > 70 && a % 2 == 1Relational and equality operators bind tighter than&&: true && true.member ? … : …The ternary operator picks one of two values.
Evaluate it like the JVM
Each step shows how the expression on that line is broken down and in which order.
Worked examples: real problems, solved and traced in memory
Operators turn values into answers: arithmetic, comparison, logical, compound assignment and increment. Each program below answers a real business question with nothing but operators. Watch the variables change on the stack after each expression.
Build a bill with compound assignment
Problem statement
A checkout adds three items to a total, applies a 10% discount, adds Rs 40 delivery, and splits the bill across 3 friends. Use +=, *=, / and %.
items 450, 299, 180; 10% off; delivery 40; 3 people
Bill: Rs 876 Each pays Rs 292, leftover Rs 0
Approach
total += priceadds to the running total.total *= 0.9applies the discount.- Whole-rupee share with
/, leftover with%.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Is it a leap year? Logical operators
Problem statement
A billing system must know whether February has 29 days. A year is a leap year if it's divisible by 4 and not by 100, or if it's divisible by 400. Check 2024, 1900 and 2000.
2024, 1900, 2000
2024: true 1900: false 2000: true
Approach
year % 4 == 0tests divisibility.- Combine with
&&(and),||(or),!=(not equal). - Store each result in a boolean.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Token numbers with ++: before or after?
Problem statement
A restaurant hands out tokens. next++ gives the current number and then increases it; ++next increases first. Hand out two tokens with next++, then peek at the following number with ++next.
tokens start at 101
Asha: 101, Ravi: 102 next is now 104, peek was 104
Approach
int t = next++;: t gets 101, next becomes 102.- Repeat for the second customer.
++nextincreases first, then gives the new value.
Solution: run it live
What happens in memory, step by step
Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.
Check yourself
Quick revision
Lesson 2.5 in one screen
- Arithmetic
+ - * / %; int / int drops decimals; % keeps the left sign. x++uses then adds;++xadds then uses.- Relational/equality give booleans.
=assigns,==compares. &&/||short-circuit;&/|always evaluate both sides.- Bitwise
& | ^ ~and shifts<< >> >>>work bit by bit; used for flags and hashing. - Ternary
cond ? a : bevaluates only the chosen side. - Precedence: postfix → unary → * / % → + − → shifts → relational → equality → & ^ | → && → || → ?: → =. Use brackets.
Interview and viva questions
What is the difference between & and && in Java?
Both can be used on booleans. && is short-circuit: it skips the right side if the left is false. & always evaluates both sides. & is also the bitwise AND for integers.
What is the output of i = i++ when i is 10?
i stays 10. i++ produces the old value 10 and increments i to 11, but then the assignment stores the produced value 10 back into i, overwriting the 11.
What is the difference between >> and >>>?
>> is an arithmetic shift that copies the sign bit, so negative numbers stay negative. >>> is a logical shift that always fills with zeros, so the result is non-negative.
Does Java support operator overloading?
Not for user-defined classes. The only built-in overload is + for String concatenation.
Why can't we write if (x = 5) in Java?
Because an assignment expression has the type of the variable (int here), and an if condition must be boolean. This rule catches a classic C bug at compile time. It only compiles if x itself is a boolean.
Practice problems
Arithmetic, comparison, logical, compound and increment operators. Predict each result first. The last three are business tasks.
Remainder
Print 17 % 5 and 20 % 5.
(none)
2 0
Show solution and explanation
public class Main {
public static void main(String[] args) {
System.out.println(17 % 5 + " " + 20 % 5);
}
}How it works: % gives the remainder after division; 0 means divisible.
Even or odd as boolean
Print whether 42 and 17 are even.
42, 17
true false
Show solution and explanation
public class Main {
public static void main(String[] args) {
System.out.println((42 % 2 == 0) + " " + (17 % 2 == 0));
}
}How it works: comparison operators produce booleans.
Compound assignment
Start x at 10; do x += 5, x *= 3, x -= 7, x /= 2 and print x.
10
19
Show solution and explanation
public class Main {
public static void main(String[] args) {
int x = 10;
x += 5;
x *= 3;
x -= 7;
x /= 2;
System.out.println(x);
}
}How it works: 10 → 15 → 45 → 38 → 19.
Ternary operator
Print "PASS" if marks (58) are 40 or more, else "FAIL", using ? :.
58
PASS
Show solution and explanation
public class Main {
public static void main(String[] args) {
int marks = 58;
System.out.println(marks >= 40 ? "PASS" : "FAIL");
}
}How it works: condition ? valueIfTrue : valueIfFalse picks one of two values.
Short-circuit &&
Show that the right side of && isn't evaluated when the left is false: divide only if the divisor isn't zero.
d = 0
ok = false
Show solution and explanation
public class Main {
public static void main(String[] args) {
int d = 0;
boolean ok = d != 0 && 100 / d > 5;
System.out.println("ok = " + ok);
}
}How it works: because d != 0 is false, Java skips 100 / d, so there's no division by zero.
Free delivery check
Free delivery if the cart is Rs 499+ or the user is a member. Check a Rs 350 cart for a member.
350, member
Free delivery: true
Show solution and explanation
public class Main {
public static void main(String[] args) {
int cart = 350;
boolean member = true;
System.out.println("Free delivery: " + (cart >= 499 || member));
}
}How it works: || is true if either side is true.
Notes for an ATM withdrawal
Dispense Rs 2,800 using Rs 500 and Rs 100 notes: print how many of each.
2800
500 x 5 100 x 3
Show solution and explanation
public class Main {
public static void main(String[] args) {
int amount = 2800;
System.out.println("500 x " + amount / 500);
System.out.println("100 x " + amount % 500 / 100);
}
}How it works: / counts big notes; % gives what's left for smaller ones. % and / have the same precedence and run left to right.
Loan eligibility in one expression
Eligible if age is 21–60 and income at least Rs 25,000. Check age 34, income 28,000.
34, 28000
Eligible: true
Show solution and explanation
public class Main {
public static void main(String[] args) {
int age = 34, income = 28000;
boolean eligible = age >= 21 && age <= 60 && income >= 25000;
System.out.println("Eligible: " + eligible);
}
}How it works: all three conditions must be true for && to be true. (Illustrative rule.)
Real-world scenario questions (asked in company interviews)
Operator bugs hide in plain sight. Decide your answer first, then open the model answer.
Free delivery for everyone
The rule is: free delivery if (cart over ₹399 OR the user is a member) AND the pincode is serviceable. The code says if (cart > 399 || isMember && serviceable). Customers in non-serviceable areas are getting “free delivery” and orders are failing. Why?
The interviewer is checking: do you know that && has higher precedence than ||?
Show a strong answer
Java reads it as cart > 399 || (isMember && serviceable). Any cart over ₹399 passes, whether the pincode is serviceable or not.
- Fix with explicit brackets:
(cart > 399 || isMember) && serviceable. - Even better, name the parts:
boolean eligible = cart > 399 || isMember;thenif (eligible && serviceable). - Add tests for each combination of the three conditions (8 cases).
Avoid: relying on memorised precedence in business rules. Brackets document intent.
ArrayIndexOutOfBoundsException: Index -2
A service picks one of 8 cache servers with servers[key.hashCode() % 8]. It works for months, then crashes with an index of −2. Someone suggests Math.abs(key.hashCode()) % 8. Is that enough?
The interviewer is checking: do you know that % can be negative and about the Math.abs(Integer.MIN_VALUE) trap?
Show a strong answer
hashCode() can be negative, and Java's % keeps the sign of the left operand, so the index can be −1 to −7.
Math.absis not enough: forInteger.MIN_VALUE,Math.absreturns MIN_VALUE itself (still negative), because +2,147,483,648 doesn't fit in an int. Some real strings have exactly that hash.- Use
Math.floorMod(key.hashCode(), 8), which always returns 0–7, or(h & 0x7fffffff) % 8. - For real systems, consider consistent hashing, so adding a server doesn't move every key.
Avoid saying: “hashCode is always positive.”
Slow requests and random NullPointerExceptions
A check reads if (verifyWithBureau(pan) & customer != null & customer.isActive()). Every request makes a slow external bureau call, and some crash with NullPointerException. What would you change?
The interviewer is checking: do you understand short-circuit evaluation and ordering conditions from cheap to expensive?
Show a strong answer
Single & evaluates every operand, so the bureau call always runs, and customer.isActive() runs even when customer is null.
- Use
&&, and order conditions from cheapest and safest to most expensive:customer != null && customer.isActive() && verifyWithBureau(pan). - Now the null check protects the method call, and the slow external call only happens for active customers.
- Measure the drop in bureau calls (and cost) after the change.
Avoid: treating & and && as interchangeable.
Conversion rate always shows 0%
A dashboard shows conversion rate as orders / visitors * 100, with both values as ints. It always shows 0%, even though 340 out of 9,000 visitors ordered. What's the bug, and how would you write it?
The interviewer is checking: do you combine operator order with integer division correctly?
Show a strong answer
Evaluation is left to right for / and * (same precedence). 340 / 9000 in int is 0, and 0 * 100 is 0.
- Use double arithmetic:
orders * 100.0 / visitorsgives about 3.78. - Or reorder for integers:
orders * 100 / visitorsgives 3, but watch for overflow on large counts (use long). - Handle
visitors == 0, and format the result to one or two decimals for display.
Avoid: “Multiply by 100 at the end.” Order and types both matter.