Operators

Master Java operators — arithmetic, comparison, logical, bitwise, and the ternary operator — with the precedence rules that cause subtle bugs.

Last reviewed: January 2025

·Java 8Java 11Java 17Java 21
✅
Quick Understanding: Java operators are symbols that perform operations on variables. The most important things to know: == compares references for objects (use .equals()), && and || short-circuit (they stop evaluating if the result is determined), and integer division truncates (5/2 = 2, not 2.5).

🔍 What Is It?

Arithmetic Operators

  • →+, -, *, /, % (modulo)
  • →Integer division truncates: 7/2 = 3
  • →Modulo works on negatives: -7 % 2 = -1

Comparison Operators

  • →==, !=, <, >, <=, >=
  • →For objects, == compares references, not values

Logical Operators

  • →&& (AND), || (OR), ! (NOT) — short-circuit evaluation
  • →& (AND), | (OR) — non-short-circuit, always evaluates both sides

Bitwise Operators

  • →& (AND), | (OR), ^ (XOR), ~ (NOT)
  • →<< (left shift), >> (signed right shift), >>> (unsigned right shift)

Assignment Operators

  • →=, +=, -=, *=, /=, %=, &=, |=, ^=

Other

  • →instanceof — type check (Java 16+: pattern matching)
  • →Ternary ? : — inline if-else
  • →+ — string concatenation when one operand is String

🎯 Why Do We Need It?

Operators are the fundamental building blocks of any computation. Understanding short-circuit evaluation prevents NullPointerExceptions. Understanding integer division prevents calculation bugs. Understanding bitwise operators is essential for working with flags, permissions, and network protocols.

🏗️ What Happens in Real Projects?

Real enterprise usage:

  • →Null-safe checks: if (user != null && user.isActive()) — short-circuit prevents NPE
  • →Permission flags: if ((permissions & READ_FLAG) != 0) — bitwise AND for flag checking
  • →Pagination: int offset = (page - 1) * pageSize
  • →Modulo for cycling: int index = counter % array.length
  • →Pattern matching instanceof (Java 16+): if (obj instanceof String s) { s.toUpperCase(); }

⚙️ How It Works

Operator Precedence (high to low, simplified)

  1. Postfix: expr++, expr--
  2. Unary: ++expr, --expr, +, -, !, ~
  3. Multiplicative: *, /, %
  4. Additive: +, -
  5. Shift: <<, >>, >>>
  6. Relational: <, >, <=, >=, instanceof
  7. Equality: ==, !=
  8. Bitwise AND: &
  9. Bitwise XOR: ^
  10. Bitwise OR: |
  11. Logical AND: &&
  12. Logical OR: ||
  13. Ternary: ? :
  14. Assignment: =, +=, etc.

Rule of thumb: when in doubt, use parentheses. Explicit is always better than relying on precedence.

💻 Example

Operators in Real Code — Practical operator usage patterns and common pitfalls.

java
// Integer division gotcha
int result = 7 / 2;           // 3, not 3.5!
double correct = 7.0 / 2;     // 3.5
double also = (double) 7 / 2; // 3.5

// Short-circuit evaluation
String name = null;
// Safe: short-circuit prevents NPE
if (name != null && name.length() > 0) {
    System.out.println(name.toUpperCase());
}

// Ternary operator
int age = 20;
String status = age >= 18 ? "adult" : "minor";

// String concatenation with +
String s2 = 1 + 2 + " hello";   // "3 hello" (1+2=3 first)
String s3 = "hello " + 1 + 2;   // "hello 12" (left to right)

// instanceof pattern matching (Java 16+)
Object obj = "Hello World";
if (obj instanceof String s) {
    System.out.println(s.length());  // s is already cast
}

// Switch expression pattern matching (Java 21)
String desc = switch (obj) {
    case Integer i -> "int: " + i;
    case String s  -> "str: " + s;
    default        -> "other";
};

🤔 Common Confusions

❓ What is the difference between & and && ?

&& is short-circuit AND — if the left side is false, the right side is NOT evaluated. & is bitwise AND (also works as logical AND but always evaluates both sides). Use && for boolean logic (it is safer and more efficient). Use & only when you explicitly need both sides evaluated or for bitwise operations on integers.

❓ Why does "hello" + 1 + 2 give "hello12" but 1 + 2 + "hello" give "3hello"?

The + operator evaluates left to right. "hello" + 1 = "hello1" (String concat), then "hello1" + 2 = "hello12". But 1 + 2 = 3 (int addition), then 3 + "hello" = "3hello" (String concat). Always use parentheses or StringBuilder when mixing types.

❓ What does the >>> operator do that >> does not?

>> is signed right shift — it preserves the sign bit (fills with 1 for negative numbers). >>> is unsigned right shift — it always fills with 0. For positive numbers they are identical. >>> is used in hash functions and bit manipulation algorithms.

🚨 Common Production Issues

Integer division returning 0 unexpectedly — int/int always truncates. A common bug: int pct = count / total * 100 always gives 0 if count < total. Fix: double pct = (double) count / total * 100.

NullPointerException from non-short-circuit evaluation — using & instead of && means the right side is evaluated even when the left is false, causing NPE on null object.

Overflow in arithmetic — int + int can overflow silently. For large calculations, use long or BigInteger.

✅ Best Practices

Always use && and || (short-circuit) for boolean logic, not & and |.

Use parentheses to make operator precedence explicit, not implicit.

Use Math.floorDiv() and Math.floorMod() for consistent behavior with negative numbers.

Prefer pattern matching instanceof (Java 16+) over cast-after-check.

Avoid nested ternary operators — use if/else for readability.

🏛️ Architect's Note

Senior Architect's Perspective

Bitwise operations are used in high-performance code: hash functions, cryptography, network protocol parsing, and permission systems. In business logic, prefer enums or EnumSet over int flags for type safety. EnumSet is internally implemented with bitwise operations but gives you type safety and readability.

💬 Frequently Asked Questions

What is the difference between pre-increment (++i) and post-increment (i++)?

++i increments first, then returns the new value. i++ returns the current value, then increments. In a standalone statement they are identical. The difference matters in expressions: int x = 5; int y = x++; gives y=5, x=6. int y = ++x; gives y=6, x=6. In modern Java, avoid using them in complex expressions — use them only as standalone statements.

What is instanceof pattern matching?

Java 16+ allows: if (obj instanceof String s) { s.toUpperCase(); }. The variable s is automatically cast and scoped to the if block. Java 21 extends this to switch expressions: switch (obj) { case String s -> s.length(); case Integer i -> i * 2; }. This eliminates the verbose cast-and-check pattern.

🎯 Key Takeaways

1Integer division always truncates — cast to double when you need decimal results
2Use && and || (short-circuit) to prevent NullPointerExceptions
3== compares references for objects — always use .equals() for value comparison
4Bitwise operators (&, |, ^, <<, >>) are essential for flags and performance-critical code
5Use parentheses to make precedence explicit
6Pattern matching instanceof (Java 16+) eliminates verbose cast patterns

🎯 Practice this topic in interviews

↗ Where this topic fits

Sources

Sources / References

Use these Core Java references to verify the concept in official docs and continue into the most relevant SplashRide pages.

Related SplashRide pages