This chapter covers Arithmetic Operators, Unary Operators, Increment/Decrement, Assignment and Compound Assignment, Relational and Equality Operators, Logical and Short-Circuit Operators, Bitwise and Shift Operators, the Ternary Operator, instanceof, Operator Precedence, Operator Associativity, Expression Evaluation, and Short-Circuit Evaluation, exactly as defined in the supplied chapter scope.
Before We Touch an Operator, Understand the Problem#
You already know that a Java program stores information in variables.
For example:
int price = 100;
int quantity = 3;At this moment Java knows two values:
price → 100
quantity → 3But storing data alone is not enough.
A real program must do something with that data.
Suppose we are building an online shopping application.
We may need to:
- calculate the total price
- check whether stock is available
- compare two prices
- increase quantity
- apply a discount
- check whether a user is eligible for an offer
- manipulate binary flags
- choose one value depending on a condition
So the next question is:
How do we tell Java to perform operations on values?
Java provides operators for this purpose.
1. What Is an Operator?#
An operator is a symbol that tells Java to perform a specific operation on one or more values.
For example:
int total = 100 + 50;Here:
100 + 50contains three parts:
100 → operand
+ → operator
50 → operandThe + operator tells Java:
Add the left operand and the right operand.
The result is:
150Operator vs Operand#
Consider:
int result = a * b;Here:
| Part | Meaning |
|---|---|
a | Operand |
* | Operator |
b | Operand |
a * b | Expression |
result = a * b | Assignment expression |
An operand is the value on which an operator works.
An operator may work on:
- one operand
- two operands
- three operands
This leads us to an important classification.
2. Operators Based on Number of Operands#
Unary Operator#
Works on one operand.
Example:
int x = 10;
x++;++ works on one variable.
Binary Operator#
Works on two operands.
Example:
int sum = 10 + 20;+ works on 10 and 20.
Ternary Operator#
Works on three operands.
Example:
int max = a > b ? a : b;Java's conditional ?: operator is commonly called the ternary operator.
3. What Is an Expression?#
We have already used the word expression several times.
Before going further, it must be clear.
An expression is a combination of values, variables, operators, and sometimes method calls that Java evaluates to produce a value.
Example:
price * quantityIf:
price = 100;
quantity = 3;then:
price * quantityevaluates to:
300Another expression:
age >= 18produces:
trueAnother:
salary > 50000 && experience >= 3also produces a boolean value.
So expressions are everywhere in Java.
4. Arithmetic Operators#
Imagine that we are implementing a billing system.
We need to:
Add prices
Subtract discounts
Multiply price × quantity
Divide totals
Find remaindersJava therefore provides arithmetic operators.
| Operator | Meaning |
|---|---|
+ | Addition |
- | Subtraction |
* | Multiplication |
/ | Division |
% | Remainder |
Addition Operator +#
public class AdditionDemo {
public static void main(String[] args) {
int first = 20;
int second = 10;
int result = first + second;
System.out.println(result);
}
}Output:
30Execution:
first = 20
second = 10
20 + 10
↓
305. + Has Two Important Roles#
There is something special about +.
With numeric values:
10 + 20it performs addition.
With a String:
"Java" + " Developer"it performs String concatenation.
Concatenation means joining values together.
Example:
public class ConcatenationDemo {
public static void main(String[] args) {
String firstName = "Amit";
String lastName = "Patil";
String fullName = firstName + " " + lastName;
System.out.println(fullName);
}
}Output:
Amit PatilA Common Interview Trap#
Predict the output:
public class ExpressionDemo {
public static void main(String[] args) {
System.out.println(10 + 20 + "Java");
System.out.println("Java" + 10 + 20);
}
}Output:
30Java
Java1020Why?
Java evaluates operands from left to right.
First line:
10 + 20 + "Java"
30 + "Java"
"30Java"Second line:
"Java" + 10 + 20
"Java10" + 20
"Java1020"If we write:
System.out.println("Java" + (10 + 20));the parentheses force addition first.
Output:
Java30Micro-checkpoint#
Remember:
Once+starts performing String concatenation, subsequent+operations continue concatenating unless parentheses force another numeric expression to be evaluated first.
6. Subtraction Operator -#
int balance = 1000;
int withdrawal = 300;
int remaining = balance - withdrawal;
System.out.println(remaining);Output:
7007. Multiplication Operator *#
Suppose one product costs ₹250 and the customer buys four.
int price = 250;
int quantity = 4;
int total = price * quantity;
System.out.println(total);Output:
10008. Division Operator /#
Division looks simple, but Java developers frequently make mistakes here.
Consider:
int result = 10 / 2;
System.out.println(result);Output:
5Now:
int result = 5 / 2;
System.out.println(result);What do you expect?
Mathematically:
5 ÷ 2 = 2.5But Java prints:
2Why?
Both operands are integers:
5
2Therefore Java performs integer division.
The fractional part is discarded.
It is not rounded.
2.5 → 2Getting a Decimal Result#
At least one operand must participate as a floating-point value.
double result = 5.0 / 2;
System.out.println(result);Output:
2.5This also works:
double result = 5 / 2.0;And:
int a = 5;
int b = 2;
double result = (double) a / b;A Very Common Mistake#
double result = 5 / 2;Some beginners expect:
2.5But the result is:
2.0Why?
First:
5 / 2 → 2Then Java converts that int result to double:
2 → 2.0The decimal information was already lost.
Correct:
double result = 5.0 / 2;or:
double result = (double) 5 / 2;9. Division by Zero#
This is where operand types matter dramatically.
Integer Division by Zero#
int x = 10;
int y = 0;
System.out.println(x / y);At runtime:
ArithmeticException: / by zeroFloating-Point Division by Zero#
double x = 10.0;
double y = 0.0;
System.out.println(x / y);Output:
InfinityFor:
System.out.println(-10.0 / 0.0);the result is:
-InfinityAnd:
System.out.println(0.0 / 0.0);produces:
NaNNaN means:
Not a Number.
Important production point#
Never assume that floating-point division by zero throws the same exception as integer division.
10. Remainder Operator %#
Suppose we divide:
10 ÷ 3We get:
Quotient = 3
Remainder = 1The % operator returns the remainder.
System.out.println(10 % 3);Output:
1Even/Odd Example#
A number is even if division by 2 leaves remainder 0.
int number = 14;
if (number % 2 == 0) {
System.out.println("Even");
} else {
System.out.println("Odd");
}Cyclic Usage#
The remainder operator is useful when values must wrap around.
Example:
int index = 7;
int size = 5;
int wrappedIndex = index % size;
System.out.println(wrappedIndex);Output:
2This idea appears in:
- circular buffers
- pagination
- rotation logic
- hash-based calculations
- alternating behavior
11. Negative Values and %#
Consider:
System.out.println(-10 % 3);Output:
-1In Java, integer remainder is consistent with:
a == (a / b) * b + (a % b)Because Java integer division truncates toward zero.
This means Java's % is technically a remainder operator, not always the mathematical modulo operation people expect for negative numbers.
For applications requiring mathematical floor-mod behavior, Java provides methods such as:
Math.floorMod(...)Example:
System.out.println(-10 % 3);
System.out.println(Math.floorMod(-10, 3));Output:
-1
212. Numeric Promotion During Arithmetic#
A new concept has appeared.
Before continuing with operators, we need to understand what Java does when operand types differ.
Suppose:
int x = 10;
double y = 2.5;
double result = x + y;Java cannot simply perform int + double without determining a common numeric type.
Java performs numeric promotion.
For common arithmetic expressions, smaller integral types such as:
byte
short
charare generally promoted to:
intbefore arithmetic.
Important Example#
byte a = 10;
byte b = 20;
// byte result = a + b;That assignment does not compile.
Why?
a + b is evaluated as an int.
So conceptually:
byte + byte
↓
int + int
↓
intCorrect:
int result = a + b;Or, if you are certain the value fits:
byte result = (byte) (a + b);But explicit narrowing can lose data.
13. Integer Overflow#
Consider:
int value = Integer.MAX_VALUE;
System.out.println(value);
System.out.println(value + 1);Output:
2147483647
-2147483648Java's ordinary integer arithmetic does not automatically throw an exception on overflow.
The value wraps according to the fixed-width two's-complement representation.
For code where overflow must be detected, APIs such as:
Math.addExact()
Math.subtractExact()
Math.multiplyExact()can be useful.
Example:
int result = Math.addExact(Integer.MAX_VALUE, 1);This throws:
ArithmeticExceptionProduction lesson#
For money, counters, IDs, quantities, financial calculations, and security-sensitive arithmetic, think explicitly about:
- range
- overflow
- precision
- validation
14. Unary Operators#
Until now, our arithmetic operators usually worked with two operands.
But sometimes we need to operate on only one value.
Java provides several unary operators.
Important ones include:
+
-
++
--
!
~15. Unary Plus +#
int number = 10;
int result = +number;result remains:
10Unary + usually has limited practical importance.
16. Unary Minus -#
Unary minus changes the sign.
int number = 10;
int result = -number;
System.out.println(result);Output:
-10If:
int number = -10;
int result = -number;then:
1017. Increment Operator ++#
Imagine a shopping cart.
Current quantity:
int quantity = 1;The customer clicks +.
We could write:
quantity = quantity + 1;Because increasing by one is extremely common, Java gives us:
quantity++;The ++ operator increases a variable by exactly 1.
18. Decrement Operator --#
Similarly:
quantity--;decreases the value by exactly 1.
19. Pre-Increment vs Post-Increment#
This distinction becomes important when the operator participates inside a larger expression.
Pre-Increment#
++xmeans:
Increment first, then produce the new value.
Post-Increment#
x++means:
Produce the current value first, then increment the variable.
20. Pre-Increment Example#
public class PreIncrementDemo {
public static void main(String[] args) {
int x = 5;
int y = ++x;
System.out.println(x);
System.out.println(y);
}
}Output:
6
6Execution:
x = 5
++x
↓
x becomes 6
↓
expression produces 6
y = 621. Post-Increment Example#
public class PostIncrementDemo {
public static void main(String[] args) {
int x = 5;
int y = x++;
System.out.println(x);
System.out.println(y);
}
}Output:
6
5Execution:
x = 5
x++
↓
expression first produces 5
↓
x becomes 6
y = 5
x = 622. Standalone Increment#
If we write:
x++;or:
++x;as standalone statements, both leave x increased by one.
Example:
int x = 5;
x++;
System.out.println(x);and:
int x = 5;
++x;
System.out.println(x);both print:
6The pre/post distinction matters primarily when the produced value participates in another expression.
23. Pre-Decrement#
int x = 5;
int y = --x;Result:
x = 4
y = 424. Post-Decrement#
int x = 5;
int y = x--;Result:
x = 4
y = 525. Dangerous Increment Expressions#
Consider:
int x = 5;
int result = x++ + ++x;Technically, Java defines the operand evaluation order, so this expression has deterministic behavior.
But that does not mean it is good code.
Execution:
x = 5
x++
produces 5
x becomes 6
++x
x becomes 7
produces 7
result = 5 + 7
= 12
final x = 7This code is difficult to read.
Preferred production style#
Instead of compressing multiple mutations into one expression:
int result = x++ + ++x;write clear separate operations when practical.
Readability usually matters more than showing that you understand operator tricks.
26. Increment Cannot Be Applied Everywhere#
This is invalid:
// 10++;Why?
10 is a literal value.
There is no variable whose stored value can be updated.
Similarly, this is invalid:
final int x = 10;
// x++;A final variable cannot be reassigned.
27. Assignment Operator =#
We use:
int age = 25;The = operator assigns the value on the right to the variable on the left.
Think:
Right side evaluated
↓
Result obtained
↓
Stored in left variableExample:
int a;
a = 10 + 20;Java first evaluates:
10 + 20 → 30Then:
a = 3028. = Is Not Equality#
One of the most important beginner rules:
= → assignment
== → equality comparisonExample:
int x = 10;means:
Put10intox.
But:
x == 10asks:
Isxequal to10?
It produces:
trueor:
false29. Chained Assignment#
Assignment operators associate from right to left.
Example:
int a;
int b;
int c;
a = b = c = 10;Conceptually:
a = (b = (c = 10))After execution:
a = 10
b = 10
c = 1030. Compound Assignment Operators#
Suppose:
int balance = 1000;
balance = balance + 500;Java provides shorter syntax:
balance += 500;Important compound assignment operators include:
| Operator | Example | ||
|---|---|---|---|
+= | x += 5 | ||
-= | x -= 5 | ||
*= | x *= 5 | ||
/= | x /= 5 | ||
%= | x %= 5 | ||
&= | x &= y | ||
| = | x | = y | ||
^= | x ^= y | ||
<<= | x <<= 2 | ||
>>= | x >>= 2 | ||
>>>= | x >>>= 2 |
31. Compound Assignment Is More Than Shorter Syntax#
Now we reach an important Java-specific rule.
Consider:
byte value = 10;
// value = value + 1;This fails to compile because:
byte + int
↓
intand Java will not implicitly narrow that int to byte.
But:
byte value = 10;
value += 1;compiles.
Why?
Compound assignment includes an implicit conversion back to the left-hand variable type.
Conceptually:
value += 1;behaves roughly like:
value = (byte) (value + 1);This difference is a classic Java interview question.
Another Important Difference#
The Java Language Specification defines compound assignment so that the left-hand expression is evaluated only once.
That matters if the left side itself performs work.
Therefore:
E1 op= E2should not always be treated as a purely textual replacement for:
E1 = E1 op E2because the evaluation count of E1 may differ.
32. Relational Operators#
Suppose our application must determine whether a user is old enough.
We need questions such as:
Is age greater than 18?
Is price less than 500?
Is score at least 40?Java provides relational operators.
| Operator | Meaning |
|---|---|
< | Less than |
> | Greater than |
<= | Less than or equal |
>= | Greater than or equal |
These produce a boolean.
33. Relational Examples#
int age = 25;
System.out.println(age > 18);
System.out.println(age < 18);
System.out.println(age >= 25);
System.out.println(age <= 20);Output:
true
false
true
false34. Equality Operators#
Sometimes we need to know whether two values are equal or different.
Java provides:
==
!=== means equal according to the operator's type-specific rules.
!= means not equal.
35. Primitive Equality#
int a = 10;
int b = 10;
System.out.println(a == b);Output:
trueFor primitive numeric values, == compares their values after the necessary numeric conversions.
36. Boolean Equality#
boolean a = true;
boolean b = false;
System.out.println(a == b);Output:
falseNormally, code such as:
if (isActive) {
}is clearer than:
if (isActive == true) {
}37. Reference Equality: A Critical Java Concept#
A new concept appears here.
Variables such as:
String
Employee
Customer
ArrayListusually hold references to objects.
For reference types, == answers:
Do these two references refer to the same object?
It does not generally mean:
Do these two objects contain logically equal data?
38. == with Strings#
Consider:
String first = new String("Java");
String second = new String("Java");
System.out.println(first == second);Output:
falseWhy?
Two separate objects were created.
Conceptually:
first ─────→ String object "Java"
second ─────→ different String object "Java"Their content looks equal, but references differ.
For logical String content comparison:
System.out.println(first.equals(second));Output:
true39. Why String == Sometimes Appears to Work#
Consider:
String first = "Java";
String second = "Java";
System.out.println(first == second);This commonly prints:
truebecause String literals can refer to the same pooled String object.
That does not make == the correct general mechanism for comparing String content.
Production rule#
Use:
first.equals(second)when you mean String content equality, with appropriate null handling.
A null-safe pattern is:
"Java".equals(value)or:
Objects.equals(first, second)when Objects is appropriate for the surrounding code.
40. Wrapper Equality Trap#
Consider:
Integer a = 127;
Integer b = 127;
System.out.println(a == b);This may print:
trueNow:
Integer a = 128;
Integer b = 128;
System.out.println(a == b);commonly prints:
falseWhy?
Wrapper objects may use cached instances for certain values.
The lesson is not to memorize a trick and use it in production.
The lesson is:
== on wrapper references tests reference identity unless unboxing/numeric promotion changes the expression.Use logical equality where object equality is intended.
41. Autounboxing Can Introduce NullPointerException#
Consider:
Integer count = null;
if (count == 0) {
System.out.println("Zero");
}To compare count with primitive 0, Java attempts to unbox count.
Conceptually:
Integer null
↓
unbox to int
↓
impossible
↓
NullPointerExceptionThis is an important production trap.
42. Floating-Point Equality and NaN#
Consider:
double value = Double.NaN;
System.out.println(value == value);Output:
falseAnd:
System.out.println(value != value);Output:
trueNaN has special floating-point comparison behavior.
Relational comparisons involving NaN such as:
value < 10
value > 10
value <= 10
value >= 10are false.
For domain-sensitive floating-point comparison, direct == may also be inappropriate because floating-point arithmetic can have representation error.
Example:
double result = 0.1 + 0.2;
System.out.println(result);
System.out.println(result == 0.3);Typical output:
0.30000000000000004
falseFor financial decimal arithmetic, developers often consider BigDecimal rather than binary floating-point types such as double.
That is a larger topic, but the operator lesson you must remember is:
Numeric-looking decimal values do not automatically behave like exact base-10 mathematics when stored as double.43. Logical Operators#
Suppose a loan should be approved only when:
age >= 18
AND
income >= 30000One condition is not enough.
We need to combine boolean expressions.
Java provides logical operators.
Important boolean operators:
&&
||
!
&
|
^The most common are:
&& → logical AND with short-circuiting
|| → logical OR with short-circuiting
! → logical NOT44. Logical AND &&#
int age = 25;
double salary = 50000;
boolean eligible = age >= 18 && salary >= 30000;
System.out.println(eligible);Both conditions must be true.
Truth table:
| A | B | A && B |
|---|---|---|
| false | false | false |
| false | true | false |
| true | false | false |
| true | true | true |
45. Logical OR ||#
Suppose a user may access an admin page if the user is either:
ADMIN
OR
SUPER_ADMINSimplified example:
boolean admin = false;
boolean superAdmin = true;
boolean allowed = admin || superAdmin;
System.out.println(allowed);Output:
trueTruth table:
| A | B | A || B |
|---|---|---|
| false | false | false |
| false | true | true |
| true | false | true |
| true | true | true |
46. Logical NOT !#
! reverses a boolean value.
boolean active = true;
System.out.println(!active);Output:
falsePractical example:
if (!isLoggedIn) {
System.out.println("Please login.");
}47. Exclusive OR ^ with Booleans#
^ can also operate on booleans.
It returns true when the boolean operands differ.
| A | B | A ^ B |
|---|---|---|
| false | false | false |
| false | true | true |
| true | false | true |
| true | true | false |
Example:
boolean emailLogin = true;
boolean phoneLogin = false;
System.out.println(emailLogin ^ phoneLogin);Output:
trueThis is less common than && and ||, but it is valid Java.
48. Short-Circuit Evaluation#
Now we reach one of the most important parts of the chapter.
Suppose we write:
A && BIf Java evaluates A and discovers:
A = falsedoes it need to evaluate B?
No.
For AND:
false && anythingwill always be:
falseTherefore Java can skip B.
This behavior is called short-circuit evaluation.
49. Short-Circuit &&#
boolean result = false && expensiveMethod();Because the left operand is false, Java does not need the right operand to determine the final answer.
The right operand is skipped.
50. Short-Circuit ||#
For OR:
true || anythingwill always be true.
Therefore:
boolean result = true || expensiveMethod();does not need to execute expensiveMethod().
51. Short-Circuiting Can Prevent Errors#
Consider:
String name = null;
if (name != null && name.length() > 3) {
System.out.println("Long name");
}Execution:
name != null
↓
false
↓
&& already knows final result is false
↓
name.length() is NOT executedTherefore no NullPointerException occurs.
If the conditions were reversed:
if (name.length() > 3 && name != null) {
}Java tries:
name.length()first.
Because name is null:
NullPointerExceptionDecision rule#
When one condition protects the safety of another condition, put the safety condition first.
52. Preventing Division by Zero#
int divisor = 0;
if (divisor != 0 && 100 / divisor > 10) {
System.out.println("Condition matched");
}The division is skipped when:
divisor == 053. && vs & for Booleans#
This is frequently asked in interviews.
Both can operate on boolean values.
But:
&& → short-circuit AND
& → evaluates both operandsExample:
public class AndDemo {
static boolean check() {
System.out.println("check() executed");
return true;
}
public static void main(String[] args) {
boolean result = false && check();
System.out.println(result);
}
}Output:
falsecheck() does not run.
Now:
boolean result = false & check();Output includes:
check() executed
falsebecause & evaluates both boolean operands.
54. || vs |#
Similarly:
|| → short-circuit OR
| → evaluates both boolean operandsIn everyday conditional logic, && and || are usually preferred when short-circuit semantics are intended.
& and | also have an important second role:
bitwise operations on integral values.
That brings us naturally to bitwise operators.
55. Why Bitwise Operators Exist#
Computers ultimately store integer values using bits.
For example, using four bits for illustration:
5 = 0101
3 = 0011Sometimes we need to manipulate individual bits.
This is common in:
- flags
- permissions
- protocols
- low-level systems
- graphics
- embedded programming
- compact state representation
- networking
- masks
Java provides bitwise operators.
56. Bitwise Operators#
Important bitwise operators:
| Operator | Meaning | |
|---|---|---|
& | Bitwise AND | |
| | Bitwise OR | |
^ | Bitwise XOR | |
~ | Bitwise complement |
They operate on integral types after Java's numeric promotion rules.
57. Bitwise AND &#
Example:
5 = 0101
3 = 0011Perform AND bit by bit:
0101
& 0011
------
0001Result:
1Java:
System.out.println(5 & 3);Output:
1AND rule:
1 & 1 → 1
otherwise → 058. Bitwise OR |#
0101
| 0011
------
01110111 is:
7Java:
System.out.println(5 | 3);Output:
759. Bitwise XOR ^#
XOR produces 1 when bits differ.
0101
^ 0011
------
0110Result:
6System.out.println(5 ^ 3);Output:
660. Bitwise Complement ~#
~ flips every bit:
0 → 1
1 → 0For Java's signed two's-complement integers:
System.out.println(~5);Output:
-6A useful identity is:
~x == -(x + 1)for ordinary two's-complement integer values.
61. Bit Flags Example#
Suppose an application uses bit flags:
int READ = 1; // 0001
int WRITE = 2; // 0010
int DELETE = 4; // 0100Give a user READ and WRITE:
int permissions = READ | WRITE;Binary:
0001
0010
----
0011Check READ permission:
boolean canRead = (permissions & READ) != 0;This pattern appears frequently in systems where multiple boolean states are packed into bits.
For ordinary business applications, enums or other expressive abstractions may often be easier to maintain. Bit masks are valuable when their compact representation or protocol compatibility is actually needed.
62. Shift Operators#
We already know that numbers are represented by bits.
Sometimes we need to move those bits left or right.
Java provides:
<< left shift
>> signed right shift
>>> unsigned right shift63. Left Shift <<#
Example:
int result = 5 << 1;Simplified binary:
5 = 00000101
shift left by 1:
00001010Result:
10System.out.println(5 << 1);Output:
10For values where no relevant overflow occurs:
x << noften corresponds to multiplication by:
2^nBut do not blindly use this as a replacement for normal multiplication.
Overflow and readability matter.
64. Signed Right Shift >>#
Example:
System.out.println(8 >> 1);Binary movement corresponds to:
8 → 4Output:
4For positive numbers, right shift often resembles division by powers of two.
For negative values, >> preserves the sign by filling high-order bits with the sign bit.
This is called sign extension.
65. Unsigned Right Shift >>>#
>>> shifts bits right but fills the high-order positions with zeros.
Example:
int value = -8;
System.out.println(value >> 1);
System.out.println(value >>> 1);The two results differ dramatically because:
>> preserves sign
>>> inserts zero bitsFor int:
-8 >> 1 → -4
-8 >>> 1 → 214748364466. Why >>> Is Called Unsigned Right Shift#
Java's commonly used integral types such as int and long are signed.
But >>> lets us perform a right shift without propagating the sign bit.
It does not transform Java's int into a completely different unsigned integer type.
It is simply a zero-fill right shift operation.
67. Shift Distance Rules#
An advanced but important rule:
For int shifts, Java uses only the low five bits of the shift distance.
Effectively the shift distance is constrained modulo 32.
For long, Java uses the low six bits.
Effectively modulo 64.
Therefore:
System.out.println(1 << 32);prints:
1because for int:
32 → effective shift distance 0Similarly:
System.out.println(1 << 33);behaves like:
1 << 1and prints:
2This is an excellent interview trap.
68. Smaller Integral Types and Shifts#
Consider:
byte value = 1;
int result = value << 2;The shift expression produces an int because smaller integral operands are promoted.
This is another reason bitwise and shift code must be written with careful awareness of type conversion.
69. Ternary Operator ?:#
Suppose we want:
If age >= 18
status = "Adult"
else
status = "Minor"Using if/else:
String status;
if (age >= 18) {
status = "Adult";
} else {
status = "Minor";
}When the goal is simply to choose between two values, Java provides the conditional operator:
condition ? valueIfTrue : valueIfFalseExample:
String status = age >= 18 ? "Adult" : "Minor";70. How Ternary Works#
int age = 20;
String status = age >= 18 ? "Adult" : "Minor";Flow:
age >= 18
↓
true
↓
choose "Adult"Only the chosen operand expression is evaluated.
71. Ternary Is an Expression#
This is important.
if/else is a statement structure.
The conditional operator produces a value.
Therefore it can participate in expressions.
Example:
int max = a > b ? a : b;72. Do Not Abuse Nested Ternary Expressions#
Possible:
String grade = score >= 80 ? "A" : score >= 60 ? "B" : score >= 40 ? "C" : "Fail";Technically valid.
But readability may become poor.
A clearer version may be:
String grade;
if (score >= 80) {
grade = "A";
} else if (score >= 60) {
grade = "B";
} else if (score >= 40) {
grade = "C";
} else {
grade = "Fail";
}Decision rule#
Use ternary when:
- the condition is simple
- you are selecting between values
- readability remains high
Prefer if/else when:
- multiple statements are required
- branching logic is complex
- nested ternaries make intent difficult to read
73. instanceof Operator#
Suppose we have a variable whose declared type is broad:
Object value;At runtime it could refer to:
String
Integer
Employee
Customer
...Sometimes we need to ask:
Does this object belong to a particular type?
Java provides:
instanceof74. Basic instanceof#
Object value = "Java";
System.out.println(value instanceof String);Output:
true75. instanceof and Inheritance#
Consider:
class Animal {
}
class Dog extends Animal {
}Now:
Dog dog = new Dog();
System.out.println(dog instanceof Dog);
System.out.println(dog instanceof Animal);Output:
true
trueA Dog object is also an instance compatible with its superclass Animal.
76. instanceof with null#
A very useful rule:
Object value = null;
System.out.println(value instanceof String);Output:
falseIt does not throw NullPointerException.
Therefore classic code such as:
if (value instanceof String) {
String text = (String) value;
}is safe from a null cast path because a null reference does not satisfy the instanceof test.
77. instanceof and Casting#
Classic Java code often uses:
Object value = "Java";
if (value instanceof String) {
String text = (String) value;
System.out.println(text.length());
}The instanceof check verifies that the runtime object is compatible with the requested type before the cast.
Without a safe relationship, an incorrect cast can produce:
ClassCastException78. Version Note: Pattern Matching for instanceof#
Modern Java versions support pattern matching syntax such as:
if (value instanceof String text) {
System.out.println(text.length());
}This removes the separate explicit cast.
However, this syntax is from later Java versions and should not be presented as Java 8 syntax.
Classic syntax remains essential when studying older Java versions:
if (value instanceof String) {
String text = (String) value;
}79. Generic Type Limitation with instanceof#
Because of Java's generic type erasure rules, code such as this is not allowed:
// if (value instanceof List<String>) {
// }But a reifiable form such as:
if (value instanceof java.util.List<?>) {
}can be used.
You do not need a complete generics lesson here.
Remember only the chapter-relevant rule:
Runtimeinstanceofchecks cannot generally test parameterized generic type arguments such asList<String>.
80. Operator Precedence#
Now imagine this expression:
int result = 10 + 5 * 2;Should Java calculate:
10 + 5 = 15
15 * 2 = 30or:
5 * 2 = 10
10 + 10 = 20Java needs rules for deciding which operator binds first.
Those rules are called operator precedence.
Because multiplication has higher precedence than addition:
10 + 5 * 2
↓
10 + 10
↓
2081. Parentheses Override Normal Grouping#
int result = (10 + 5) * 2;Now:
10 + 5
↓
15
15 * 2
↓
30Parentheses are not only for changing behavior.
They can also improve readability.
In production code:
Clear intent is often better than relying on readers to remember a large precedence table.
82. Practical Precedence Order#
From higher precedence toward lower precedence, an important simplified Java order is:
| Level | Operators | ||
|---|---|---|---|
| High | postfix expr++, expr-- | ||
unary ++, --, +, -, !, ~ | |||
multiplicative *, /, % | |||
additive +, - | |||
shift <<, >>, >>> | |||
relational <, >, <=, >=, instanceof | |||
equality ==, != | |||
bitwise AND & | |||
bitwise XOR ^ | |||
bitwise OR | | |||
logical AND && | |||
logical OR | | | |||
ternary ?: | |||
| Low | assignments =, +=, -=, etc. |
Parentheses and primary expressions conceptually bind more tightly than these operator groups.
83. Precedence Example#
Predict:
boolean result = 10 > 5 && 3 < 1 || true;Grouping:
(10 > 5) && (3 < 1) || trueThen:
true && false || true&& has higher precedence than ||:
false || trueFinal result:
true84. Operator Associativity#
Precedence answers:
Which operator group binds first?
Associativity answers:
When operators of the same precedence appear together, how are they grouped?
Example:
int result = 20 - 5 - 3;Subtraction is left-associative:
(20 - 5) - 3Result:
12Not:
20 - (5 - 3)which would be:
1885. Right Associativity#
Assignment operators associate right-to-left.
a = b = c = 10;Grouping:
a = (b = (c = 10))The conditional operator also groups right-associatively.
86. Associativity Is NOT Evaluation Order#
This distinction is extremely important.
Students often believe:
If an operator is right-associative, Java must evaluate operands from right to left.
That is incorrect.
Associativity determines grouping.
Java has separate rules governing operand evaluation, and Java generally evaluates operand expressions from left to right.
Example:
int result = first() + second();first() is evaluated before second().
This predictable evaluation order distinguishes Java from languages or contexts where operand evaluation order may be less strictly defined.
87. Expression Evaluation#
Let us examine an expression slowly:
int result = 10 + 20 * 3;Java conceptually determines grouping according to precedence:
10 + (20 * 3)Then computes:
20 * 3 = 60then:
10 + 60 = 70and finally:
result = 7088. Method Calls Inside Expressions#
int result = getA() + getB();Java evaluates:
getA()
then
getB()
then
+If the methods have side effects, their order can matter.
Example:
public class EvaluationOrderDemo {
static int first() {
System.out.println("first");
return 10;
}
static int second() {
System.out.println("second");
return 20;
}
public static void main(String[] args) {
int result = first() + second();
System.out.println(result);
}
}Output:
first
second
3089. Side Effects Inside Expressions#
A side effect means an expression does more than simply calculate a value.
Examples include:
- changing a variable
- writing output
- modifying an object
- performing I/O
Increment operators create side effects.
Example:
int x = 5;
int result = x++ + 10;The expression:
- produces a value
- changes
x
This is valid, but excessive side effects inside complex expressions make code harder to reason about.
90. Constant Expressions and Division by Zero#
There is an important distinction.
This:
int zero = 0;
int result = 10 / zero;can compile and then fail at runtime with:
ArithmeticExceptionBut a compile-time constant integer expression such as:
// int result = 10 / 0;is rejected during compilation.
This is because the compiler can already determine that the constant integer expression contains division by zero.
91. Arithmetic Promotion Summary#
For ordinary binary numeric operators, a useful mental model is:
If double involved → double
else if float involved → float
else if long involved → long
else → intTherefore:
byte + byte → int
short + short → int
char + char → int
int + long → long
long + float → float
float + double → doubleThis simplified model covers the common binary numeric-promotion behavior you will repeatedly encounter.
92. char Is Numeric in Arithmetic Expressions#
Consider:
char ch = 'A';
System.out.println(ch + 1);'A' has numeric Unicode value:
65So:
65 + 1 → 66Output:
66If you want a character:
char next = (char) (ch + 1);
System.out.println(next);Output:
B93. Commonly Confused Concepts#
= vs ==#
= | == |
|---|---|
| Assignment | Equality comparison |
| Stores value | Produces boolean |
x = 10 | x == 10 |
== vs .equals()#
== | .equals() |
|---|---|
| Operator | Method |
| Primitive value comparison where applicable | Object-defined logical equality |
| Reference identity for references | Usually logical/content equality when properly implemented |
| Cannot be overridden | Method behavior can be overridden |
Decision rule:
Comparing primitives?
→ usually ==
Need object identity?
→ ==
Need logical object equality?
→ equals()&& vs &#
&& | & |
|---|---|
| Boolean only | Boolean or integral |
| Short-circuits | Evaluates both boolean operands |
| Common conditional operator | Boolean non-short-circuit or bitwise AND |
|| vs |#
|| | | |
|---|---|
| Boolean only | Boolean or integral |
| Short-circuits | Evaluates both boolean operands |
| Common logical OR | Boolean non-short-circuit or bitwise OR |
>> vs >>>#
>> | >>> |
|---|---|
| Signed right shift | Zero-fill right shift |
| Preserves sign bit | Inserts zero bits |
| Negative values usually remain negative | Negative values may become large positive values |
Pre-Increment vs Post-Increment#
++x | x++ |
|---|---|
| Increment first | Produce old value first |
| Expression gives new value | Expression gives old value |
| Standalone effect same | Standalone effect same |
94. Operator Decision Rules#
Need arithmetic?
→ + - * / %
Need to increase/decrease exactly one?
→ ++ or --
Need to assign?
→ =
Need update-and-assign?
→ += -= *= /= %= etc.
Need numeric ordering?
→ < > <= >=
Need equality?
→ == or !=
→ for logical object equality consider equals()
Need both boolean conditions?
→ &&
Need either boolean condition?
→ ||
Need reverse boolean?
→ !
Need bit-level AND/OR/XOR?
→ & | ^
Need flip integral bits?
→ ~
Need move bits?
→ << >> >>>
Need choose one of two values?
→ ?:
Need runtime type compatibility check?
→ instanceof95. Common Mistakes#
Mistake 1 — Expecting Decimal Result from Integer Division#
Mistake:
double average = 5 / 2;Why Developers Make It:
The variable receiving the result is double.
Why It Is Wrong/Risky:
5 / 2 is completed using integer arithmetic before assignment.
Possible Consequence:
Incorrect calculations.
Preferred Approach:
double average = 5.0 / 2;Debugging Clue:
Decimal portions unexpectedly disappear.
Interview Connection:
Frequently appears in output questions.
Mistake 2 — Using == for String Content#
Risky:
if (name == "Java") {
}Problem:
Reference identity may be tested instead of logical String content.
Preferred:
if ("Java".equals(name)) {
}or another appropriate null-safe equality strategy.
Mistake 3 — Putting Unsafe Condition First#
Risky:
if (name.length() > 3 && name != null) {
}Consequence:
Potential NullPointerException.
Preferred:
if (name != null && name.length() > 3) {
}Mistake 4 — Using & When && Was Intended#
if (object != null & object.isValid()) {
}Both sides are evaluated.
If object is null:
NullPointerExceptionPreferred:
if (object != null && object.isValid()) {
}Mistake 5 — Assuming byte + byte Returns byte#
byte a = 10;
byte b = 20;
// byte c = a + b;Arithmetic promotes the operands.
Use:
int c = a + b;Mistake 6 — Overusing Increment Inside Complex Expressions#
Risky readability:
int result = x++ + ++x * x--;Even if you can calculate it, teammates should not need to solve a puzzle to understand production code.
Prefer explicit steps.
Mistake 7 — Assuming Integer Overflow Throws Automatically#
int value = Integer.MAX_VALUE;
value++;No ordinary overflow exception is automatically thrown.
Validate ranges or use exact arithmetic helpers when required.
Mistake 8 — Comparing Floating-Point Results with Exact ==#
Risky for calculated decimal values:
double result = 0.1 + 0.2;
if (result == 0.3) {
}Floating-point representation can make exact comparison unsuitable for the requirement.
Mistake 9 — Treating % as Mathematical Modulo for Negative Inputs#
System.out.println(-10 % 3);produces:
-1If your algorithm requires non-negative floor-mod semantics, examine Math.floorMod().
Mistake 10 — Believing >>> Creates an Unsigned Type#
It does not.
It performs zero-fill right shifting.
Mistake 11 — Relying on Precedence in Hard-to-Read Expressions#
Valid:
if (a > b && c < d || enabled) {
}Clearer when the intended grouping matters:
if ((a > b && c < d) || enabled) {
}Mistake 12 — Confusing Associativity with Evaluation Order#
Associativity decides grouping.
It does not mean method calls are necessarily evaluated according to the associativity direction.
Java operand evaluation follows its own defined order.
96. Production Perspective#
Operators are basic language features, but operator mistakes cause real defects.
Important production concerns include:
Correctness#
Be careful with:
- integer division
- overflow
- narrowing conversions
- floating-point precision
- negative remainder behavior
Null Safety#
Short-circuit conditions often protect operations:
user != null && user.isActive()Readability#
Prefer:
boolean eligible = age >= 18 && hasPermission;over unnecessarily clever bitwise or nested ternary constructions.
Maintainability#
Parentheses can make intent clearer even when precedence already produces the same result.
Security#
Overflow or incorrect numeric validation can become security issues in sensitive code.
Performance#
Short-circuit operators can avoid unnecessary work:
cached || expensiveLookup()But correctness should come before micro-optimization.
Financial Applications#
Do not treat ordinary double arithmetic as exact decimal currency arithmetic without understanding its implications.
Testing#
Test boundaries such as:
0
1
-1
Integer.MAX_VALUE
Integer.MIN_VALUE
null
division by zero
negative operands
equal operands97. Complete Chapter Revision#
One-Line Definitions#
Operator: Symbol that performs an operation.
Operand: Value on which an operator acts.
Expression: Combination evaluated to produce a value.
Arithmetic operator: Performs arithmetic such as +, -, *, /, %.
Unary operator: Operates on one operand.
Increment: ++, increases variable by one.
Decrement: --, decreases variable by one.
Assignment: =, stores a right-side value into a left-side variable.
Relational operator: Compares ordering and produces boolean.
Equality operator: == or !=.
Short-circuit: Skips unnecessary evaluation of the right operand.
Bitwise operator: Manipulates integral values at bit level.
Shift operator: Moves bit patterns left or right.
Ternary operator: condition ? a : b.
instanceof: Checks runtime type compatibility.
Precedence: Determines operator grouping priority.
Associativity: Determines grouping among operators of the same precedence.
98. If You Remember Only 10 Things#
=assigns;==compares.5 / 2produces2, not2.5.byte + bytenormally producesint.x++produces the old value before increment;++xproduces the new value.&&and||short-circuit.&and|do not short-circuit when used with booleans.==compares reference identity for ordinary reference comparisons; use logical equality methods when content equality is intended.>>sign-extends;>>>zero-fills.- Precedence and associativity are not the same as operand evaluation order.
- Prefer readable expressions over clever operator puzzles.
99. Final Knowledge Map#
Java Operators and Expressions
│
├── Foundation
│ ├── Operator
│ ├── Operand
│ ├── Expression
│ └── Unary / Binary / Ternary
│
├── Arithmetic
│ ├── +
│ ├── -
│ ├── *
│ ├── /
│ ├── %
│ ├── Integer Division
│ ├── Numeric Promotion
│ ├── Overflow
│ └── Floating-Point Behavior
│
├── Unary
│ ├── Unary +
│ ├── Unary -
│ ├── ++
│ ├── --
│ ├── Pre-Increment
│ ├── Post-Increment
│ ├── Pre-Decrement
│ └── Post-Decrement
│
├── Assignment
│ ├── =
│ ├── +=
│ ├── -=
│ ├── *=
│ ├── /=
│ ├── %=
│ └── Bitwise/Shift Compound Assignments
│
├── Comparison
│ ├── <
│ ├── >
│ ├── <=
│ ├── >=
│ ├── ==
│ ├── !=
│ ├── Primitive Equality
│ └── Reference Equality
│
├── Logical
│ ├── &&
│ ├── ||
│ ├── !
│ ├── Boolean &
│ ├── Boolean |
│ ├── Boolean ^
│ └── Short-Circuit Evaluation
│
├── Bitwise
│ ├── &
│ ├── |
│ ├── ^
│ └── ~
│
├── Shifts
│ ├── <<
│ ├── >>
│ ├── >>>
│ └── Shift-Distance Masking
│
├── Conditional
│ └── ?:
│
├── Type Checking
│ └── instanceof
│
└── Expression Rules
├── Precedence
├── Associativity
├── Left-to-Right Operand Evaluation
├── Numeric Promotion
├── Side Effects
└── Short-Circuiting