Java Operators: Integer Division Bug Costs £5,000
Integer division bug: 1000/3 becomes 333 in Java, not 333.33, causing £5,000 invoice error.
20+ years shipping production Java in banking & fintech. Drawn from code that ran under real load.
- Operators are symbols that perform operations on data (calculate, compare, assign, or combine)
- Arithmetic: + - * / % ++ -- for numeric calculations
- Relational: == != > < >= <= for comparisons, returning boolean
- Logical: && || ! combine boolean conditions with short-circuit evaluation
- Bitwise: & | ^ ~ << >> >>> for low-level bit manipulation
- Assignment: = += -= *= /= %= update variables in place
- Precedence: parentheses always clarify intent; integer division truncates silently
Java operators are the fundamental building blocks for expressing computations, comparisons, and assignments in code. They're not just symbols—they're the language's way of translating your intent into machine operations. The infamous integer division bug, where 5 / 2 yields 2 instead of 2.5, cost a UK trading firm £5,000 in 2020 when a developer assumed floating-point behavior.
This happens because Java's / operator performs integer division when both operands are integers, truncating the fractional part. You'd hit the same wall with % (modulus) giving 1 for 5 % 2, which is correct for integers but surprises newcomers expecting decimal math.
Java provides six categories of operators, each with specific use cases and pitfalls. Arithmetic operators (+, -, *, /, %) work like a basic calculator but with type-dependent behavior—mixing int and double triggers implicit widening conversion.
Relational operators (<, >, ==, !=) and logical operators (&&, ||, !) let you build boolean conditions for if statements and loops, but short-circuit evaluation in && and || can mask side effects if you're not careful. Assignment operators (=, +=, -=) reduce boilerplate, but compound assignments like x += 1 silently cast the result to the left-hand type, which can lose precision when mixing int and long.
Operator precedence determines evaluation order when expressions combine multiple operators. Java follows a strict hierarchy: postfix (++, --) before unary (+, -, !), then multiplicative (*, /, %), additive (+, -), relational, equality, logical, and finally assignment.
This means 2 + 3 * 4 evaluates to 14, not 20. When in doubt, use parentheses—they're free and prevent the kind of bugs that cost real money. Bitwise operators (&, |, ^, ~, <<, >>, >>>) operate on individual bits, useful for flags, permissions, or performance-critical code where you'd replace modulo with & (n-1) for power-of-two boundaries.
But don't reach for bitwise tricks unless profiling proves they're necessary—readability matters more than micro-optimizations in most business applications.
Think of Java operators like the buttons on a calculator. The '+' button adds two numbers, the '>' button checks which number is bigger, and the '==' button asks 'are these two things the same?' In Java, operators are the symbols that tell the program what to DO with your data. Without them, you'd have a bunch of numbers and words sitting there doing absolutely nothing — operators are what bring your data to life.
Every useful program ever written does one of three things: it calculates something, it makes a decision, or it does both. When you open a banking app and it shows your balance after a purchase, that's subtraction. When Netflix decides whether to show you a 'Kids Mode' option based on your account type, that's a comparison. Every single one of those actions is powered by operators — and they're arguably the most fundamental tool in any Java developer's toolbox.
Why Java Integer Division Is Not Your Math Teacher's Division
Java operators are symbols that perform operations on variables and values. The core mechanic is that each operator has a fixed precedence and associativity, and for arithmetic on integers, the result type is always int (or long if any operand is long). This means that dividing two integers truncates toward zero — it does not round or produce a fraction. For example, 5 / 2 yields 2, not 2.5.
This behavior is defined by the Java Language Specification (JLS §15.17.2) and is not a bug — it's a design choice for performance and predictability. The key property in practice: integer division discards the remainder entirely. If you need a fractional result, you must cast at least one operand to a floating-point type (double or float) before the operation. The remainder operator % gives you the discarded value: 5 % 2 == 1.
Use integer division when you need whole-number results: array indices, loop counters, page numbers, or any count where fractional values are meaningless. It matters in real systems because a misplaced integer division can silently truncate critical values — think currency calculations, progress percentages, or time intervals — leading to logic errors that are hard to trace. Always check whether your operands are ints when you expect a double.
Arithmetic Operators — Java as Your Personal Calculator
Arithmetic operators do exactly what they sound like — they perform maths. Java gives you six of them: addition (+), subtraction (-), multiplication (*), division (/), modulus (%), and the increment/decrement shortcuts (++ and --). You already know the first four from school. The one that surprises beginners is the modulus operator (%). It gives you the remainder after division. So 10 % 3 gives you 1, because 10 divided by 3 is 3 with 1 left over. This is incredibly useful in real programs — for example, checking if a number is even or odd by seeing if number % 2 equals zero. The increment operator (++) simply adds 1 to a variable. Writing score++ is identical to writing score = score + 1, just shorter and cleaner. You'll use this constantly inside loops. The decrement operator (--) does the opposite — subtracts 1. One subtle thing: there's a difference between ++score (pre-increment) and score++ (post-increment) when you use them inside expressions. We'll cover that in the Gotchas section — it trips up almost everyone at first.
public class ArithmeticOperatorsDemo { public static void main(String[] args) { int totalPrice = 250; // starting price in pence int discountAmount = 30; // discount to apply int numberOfItems = 3; // items in the basket // Basic arithmetic — works exactly like a calculator int priceAfterDiscount = totalPrice - discountAmount; System.out.println("Price after discount: " + priceAfterDiscount); // 220 int totalForAllItems = priceAfterDiscount * numberOfItems; System.out.println("Total for all items: " + totalForAllItems); // 660 // Integer division — IMPORTANT: both values are int, so result is also int // Any decimal part is simply dropped (not rounded) int sharePerPerson = totalForAllItems / 2; System.out.println("Each person pays: " + sharePerPerson); // 330 // Modulus — gives us the REMAINDER after division // Great for checking even/odd, or wrapping values int leftoverPence = totalForAllItems % 7; System.out.println("Remainder when split 7 ways: " + leftoverPence); // 2 // Checking if a number is even — a classic modulus use case int quantity = 8; if (quantity % 2 == 0) { System.out.println(quantity + " is an even number"); // prints this } // Increment — adds 1 to the variable, shorter than writing score = score + 1 int score = 10; score++; // score is now 11 System.out.println("Score after increment: " + score); // 11 // Decrement — subtracts 1 int livesRemaining = 3; livesRemaining--; // livesRemaining is now 2 System.out.println("Lives remaining: " + livesRemaining); // 2 } }
int shares = total / count; where count was 3 and total was 1000 — shares became 333 instead of 333.33.(double) a / b or a * 1.0 / b when you need a decimal result.Relational and Logical Operators — Teaching Java to Make Decisions
If arithmetic operators are the calculator, relational operators are the judge. They compare two values and return a boolean — either true or false. That's it. There are six of them: == (equals), != (not equals), > (greater than), < (less than), >= (greater than or equal to), and <= (less than or equal to). Notice that equality uses TWO equals signs (==), not one. A single = means assignment (you're setting a value). Two == means comparison (you're asking a question). This is one of the most common beginner mistakes in any language. Logical operators let you chain those comparisons together. AND (&&) means both conditions must be true. OR (||) means at least one must be true. NOT (!) flips a boolean — true becomes false and vice versa. Think of && like a nightclub bouncer checking two ID criteria at once: 'Are you over 18 AND do you have valid ID?' Both must pass. Think of || like a door that opens if you have a keycard OR you know the code — either one is enough.
public class RelationalAndLogicalDemo { public static void main(String[] args) { int userAge = 20; boolean hasValidMembership = true; double accountBalance = 150.75; double minimumRequired = 100.00; // --- RELATIONAL OPERATORS --- // Each comparison produces a boolean: true or false boolean isAdult = userAge >= 18; System.out.println("Is user an adult? " + isAdult); // true boolean balanceIsSufficient = accountBalance > minimumRequired; System.out.println("Balance sufficient? " + balanceIsSufficient); // true boolean isExactlyTwenty = userAge == 20; System.out.println("Is user exactly 20? " + isExactlyTwenty); // true boolean isNotTwenty = userAge != 20; System.out.println("Is user NOT 20? " + isNotTwenty); // false // --- LOGICAL OPERATORS --- // && (AND) — BOTH sides must be true for the result to be true // Real use: user can access premium content only if adult AND has membership boolean canAccessPremiumContent = isAdult && hasValidMembership; System.out.println("Can access premium content? " + canAccessPremiumContent); // true // || (OR) — AT LEAST ONE side must be true // Real use: show warning if balance is low OR membership has expired boolean membershipExpired = false; boolean showWarning = !balanceIsSufficient || membershipExpired; System.out.println("Show account warning? " + showWarning); // false // ! (NOT) — flips the boolean value boolean isLoggedOut = !hasValidMembership; // hasValidMembership is true, so this is false System.out.println("Is user logged out? " + isLoggedOut); // false // Combining everything — a realistic access check if (isAdult && hasValidMembership && balanceIsSufficient) { System.out.println("Access granted — welcome to the platform!"); } else { System.out.println("Access denied — check your account."); } } }
obj != null && obj.isReady().= (assignment) with == (comparison).Assignment and Compound Assignment Operators — Writing Less, Doing More
The basic assignment operator (=) stores a value into a variable. You've already seen it: int score = 10. That's it doing its job. But Java also gives you compound assignment operators, which combine an arithmetic operation with assignment in one step. Instead of writing totalScore = totalScore + 50, you write totalScore += 50. They're shorthand — nothing more, nothing less. The full set is: += (add and assign), -= (subtract and assign), *= (multiply and assign), /= (divide and assign), and %= (modulus and assign). Beyond being shorter to type, they're also clearer to read. When a teammate sees totalScore += 50 they instantly know you're adding to an existing value — they don't have to parse both sides of a longer expression to figure that out. There's also the ternary operator (?:), which is a compact way to write a simple if-else in a single line. It looks unusual at first, but once it clicks, you'll use it constantly for concise value assignment. The structure is: condition ? valueIfTrue : valueIfFalse. Think of it as asking a yes/no question inline: 'Is the temperature above 25? If yes, use sunscreen; if no, use a jacket'.
public class AssignmentOperatorsDemo { public static void main(String[] args) { int playerScore = 100; // basic assignment — storing 100 into playerScore // Compound assignment operators — shorthand for common operations playerScore += 50; // same as: playerScore = playerScore + 50 System.out.println("After bonus points: " + playerScore); // 150 playerScore -= 20; // same as: playerScore = playerScore - 20 System.out.println("After penalty: " + playerScore); // 130 playerScore *= 2; // same as: playerScore = playerScore * 2 (double multiplier active) System.out.println("After double multiplier: " + playerScore); // 260 playerScore /= 4; // same as: playerScore = playerScore / 4 System.out.println("After score divided: " + playerScore); // 65 playerScore %= 10; // same as: playerScore = playerScore % 10 (keep only the ones digit) System.out.println("Remainder kept: " + playerScore); // 5 // --- TERNARY OPERATOR --- // Structure: condition ? valueIfTrue : valueIfFalse // Think of it as a one-line if-else for simple value decisions int temperature = 28; // Standard if-else version (verbose): // String advice; // if (temperature > 25) { advice = "wear sunscreen"; } // else { advice = "bring a jacket"; } // Ternary version (clean and concise): String weatherAdvice = (temperature > 25) ? "wear sunscreen" : "bring a jacket"; System.out.println("Weather advice: " + weatherAdvice); // wear sunscreen // Another real-world example — labelling a value int cartItemCount = 1; String itemLabel = (cartItemCount == 1) ? "item" : "items"; System.out.println("You have " + cartItemCount + " " + itemLabel + " in your cart."); // Output: You have 1 item in your cart. } }
temp += 0.5; on an int variable truncates to int, same as division.a += 1 instead of a = a + 1 avoids repeating the variable name and reduces typo risk.+=, -=, etc.) are shorthand for update-then-assign.?:) is a compact if-else for single-value decisions.Operator Precedence — Why Java Doesn't Always Calculate Left to Right
Here's something that surprises almost every beginner: Java doesn't always evaluate operators from left to right. It follows operator precedence — a hierarchy of which operators get calculated first, just like the BODMAS/PEMDAS rule you learned in maths class. Multiplication and division happen before addition and subtraction. Parentheses override everything. Without understanding this, you'll write expressions that produce completely unexpected results and spend hours debugging something that looks correct at first glance. The general order from highest to lowest priority is: parentheses first, then increment/decrement, then multiplication/division/modulus, then addition/subtraction, then relational comparisons, then equality checks, then logical AND, then logical OR, and finally assignment. You do not need to memorise this entire list right now. The practical rule that will save you 95% of the time is this: when in doubt, use parentheses. They make your intent crystal clear to both Java and to anyone reading your code later. Explicit is always better than clever when it comes to operator precedence.
public class OperatorPrecedenceDemo { public static void main(String[] args) { // --- WITHOUT PARENTHESES — precedence decides the order --- // Multiplication happens BEFORE addition, just like in maths int resultWithoutBrackets = 2 + 3 * 4; // Java calculates: 2 + (3 * 4) = 2 + 12 = 14 System.out.println("Without brackets: " + resultWithoutBrackets); // 14 // --- WITH PARENTHESES — you control the order --- int resultWithBrackets = (2 + 3) * 4; // Java calculates: (5) * 4 = 20 System.out.println("With brackets: " + resultWithBrackets); // 20 // Real-world example: calculating a discount correctly double originalPrice = 200.0; double discountPercent = 10.0; double shippingCost = 15.0; // WRONG — precedence causes a bug here: // Java calculates: 200.0 - (10.0 / 100.0 * 200.0) + 15.0 // That's actually correct here, but watch what happens when intent is ambiguous // CLEAR — parentheses show exactly what you intend: double discountAmount = (discountPercent / 100.0) * originalPrice; // 20.0 double finalPrice = originalPrice - discountAmount + shippingCost; System.out.println("Discount amount: £" + discountAmount); // £20.0 System.out.println("Final price: £" + finalPrice); // £195.0 // --- RELATIONAL before LOGICAL in precedence --- int userAge = 22; double userBalance = 80.0; // This works correctly because > and < are evaluated BEFORE && // So Java reads it as: (userAge > 18) && (userBalance > 50.0) boolean isEligible = userAge > 18 && userBalance > 50.0; System.out.println("User is eligible: " + isEligible); // true // Pre-increment vs post-increment — a precedence-related gotcha int counter = 5; int postIncrementResult = counter++; // counter's CURRENT value (5) is assigned, THEN counter becomes 6 System.out.println("Post-increment result: " + postIncrementResult); // 5 System.out.println("Counter after post-increment: " + counter); // 6 int preIncrementResult = ++counter; // counter becomes 7 FIRST, then 7 is assigned System.out.println("Pre-increment result: " + preIncrementResult); // 7 System.out.println("Counter after pre-increment: " + counter); // 7 } }
total = price - discount + tax * 0.08.if ((a > b) && (c != d)).Bitwise Operators — Manipulating Bits for Flags and Performance
Bitwise operators operate directly on the bits of integer types (int, long, short, byte, char). They are not used in everyday business logic, but they shine when you need compact flags, low-level network protocols, or performance-critical masking. Java has six bitwise operators: AND (&), OR (|), XOR (^), NOT (~), left shift (<<), right shift (>>), and unsigned right shift (>>>). The bitwise AND (&) compares each bit: if both bits are 1, result bit is 1; otherwise 0. Bitwise OR (|): if either bit is 1, result bit is 1. XOR (^): if bits differ, result is 1. NOT (~): flips every bit (one's complement). Shifts move bits left or right: << multiplies by 2^shift, >> divides by 2^shift (preserving sign), >>> fills left with zeros. The most common use case is storing multiple boolean flags in a single int using bit masks. For instance, user permissions: READ=1, WRITE=2, EXECUTE=4. Combine: permissions = READ | WRITE; Check: if ((permissions & EXECUTE) == 0) means user cannot execute. This is how Unix file permissions work, and it's still used in high-performance Java applications.
public class BitwiseOperatorsDemo { public static void main(String[] args) { // --- Define permission flags as powers of 2 --- final int READ = 1 << 0; // 0001 = 1 final int WRITE = 1 << 1; // 0010 = 2 final int EXECUTE = 1 << 2; // 0100 = 4 // Combine permissions using bitwise OR int userPermissions = READ | WRITE; // 0011 = 3 System.out.println("User permissions: " + userPermissions); // 3 // Check if user has READ permission using bitwise AND boolean canRead = (userPermissions & READ) != 0; System.out.println("Can read? " + canRead); // true // Check if user has EXECUTE permission boolean canExecute = (userPermissions & EXECUTE) != 0; System.out.println("Can execute? " + canExecute); // false // Add EXECUTE permission using OR userPermissions |= EXECUTE; // 0111 = 7 System.out.println("Updated permissions: " + userPermissions); // 7 // Remove WRITE permission using AND with complement userPermissions &= ~WRITE; // 0101 = 5 System.out.println("After removing WRITE: " + userPermissions); // 5 // XOR toggles a flag userPermissions ^= EXECUTE; // 0001 = 1 (EXECUTE removed) System.out.println("After toggling EXECUTE: " + userPermissions); // 1 // --- Bit shifts --- int value = 8; // 1000 System.out.println("value << 1: " + (value << 1)); // 16 (10000) System.out.println("value >> 1: " + (value >> 1)); // 4 (0100) int negative = -8; // 11111111 11111111 11111111 11111000 System.out.println("negative >> 1: " + (negative >> 1)); // -4 (preserves sign bit) System.out.println("negative >>> 1: " + (negative >>> 1)); // 2147483644 (fills with 0) } }
- AND (&): both must be ON for the result to be ON — like two switches in series
- OR (|): at least one ON — like switches in parallel
- XOR (^): ON only if they are different — like a hallway light with two switches
- NOT (~): flips every switch — ON ↔ OFF for every bit
- Shift (<<, >>, >>>): moves all switches left or right — fills new positions with 0 or sign bit
Ternary Operator — The One-Liner That Saves or Dooms You
The ternary operator ? : is Java's only ternary operator. It evaluates a boolean condition and returns one of two expressions. Junior devs love it because it's concise. Senior devs respect it because it eliminates if-else clutter in assignment logic. But here's the trap: nesting ternaries creates unreadable garbage that passes code review only because nobody wants to untangle it. Use it for simple binary choices — assigning a default value, picking a message based on a flag, or handling null checks before Java 14's Objects.requireNonNullElse. If your ternary spans more than one line or nests another ternary, stop. Extract it into a method or use a switch expression instead. The compiler evaluates only the chosen branch — the other branch's code must compile but never executes. This matters when you call methods with side effects inside a ternary. Don't. Keep side effects out of conditionals. The rule: one ternary per expression, zero side effects, always assign the result immediately.
// io.thecodeforge import java.math.BigDecimal; public class DiscountCalculator { public BigDecimal applyDiscount(Order order) { // Good: single ternary, no side effects BigDecimal rate = order.isPremium() ? new BigDecimal("0.20") : new BigDecimal("0.05"); // Bad: nested ternary — don't do this // BigDecimal result = order.isPremium() ? order.getValue().multiply(new BigDecimal("0.80")) : order.isVeteran() ? order.getValue().multiply(new BigDecimal("0.85")) : order.getValue(); return order.getValue().multiply(BigDecimal.ONE.subtract(rate)); } }
:, refactor.Null Safety — The instanceof Operator and Pattern Matching
Every Java dev learns instanceof early. It checks whether an object is an instance of a specific type. In Spring Boot, you'll use it when processing heterogeneous event payloads from a message queue or handling polymorphic deserialization. The classic pattern: check instanceof, then cast. That cast is boilerplate. Java 16 introduced pattern matching for instanceof, collapsing check and cast into one line. The variable is scoped to the if-block, so you can't accidentally use it outside. This eliminates ClassCastExceptions at the source. But remember: instanceof on null returns false. Always. Don't check for null before instanceof — it's redundant. For null-safe type checking in streams, use filter(MyClass.class::isInstance).map(MyClass.class::cast) — it reads cleaner than a chain of if-instanceof blocks. In Spring Boot, pattern matching shines in @EventListener methods that handle events from an interface type. Stop writing if (event instanceof OrderCreated) followed by OrderCreated oc = (OrderCreated) event. Write if (event instanceof OrderCreated oc) and use oc directly.
// io.thecodeforge import org.springframework.context.event.EventListener; import org.springframework.stereotype.Component; @Component public class EventRouter { @EventListener public void handleDomainEvent(Object event) { // Java 16+ pattern matching: no explicit cast if (event instanceof OrderCreated oc) { oc.getOrderId(); // oc is already cast } else if (event instanceof PaymentFailed pf) { alertFraudTeam(pf.getUserId()); } else { log.warn("Unhandled event type: {}", event.getClass().getSimpleName()); } } private void alertFraudTeam(String userId) { // relevant code } }
Integer Division Bug Causes £5,000 Invoice Error
- Never use int for financial calculations that involve division
- Always cast to double before division when decimal precision is needed
- Add unit tests with non-divisible amounts to catch truncation bugs
- Use BigDecimal for high-precision monetary work; double is acceptable when rounding at display is controlled
int / int patterns in code review.= instead of comparison ==. Add parentheses around conditions. Use Yoda conditions (if (10 == x)) to catch accidental assignment.< not <=.System.out.println(7 / 2); // prints 3System.out.println(7.0 / 2); // prints 3.5(double) a / b or a * 1.0 / bif (x = 5) { ... } // compiles in some languages, but Java will error for boolean; for non-boolean? Actually Java won't compile this for int types. But for boolean: boolean flag = false; if (flag = true) // always entersAlways compile with warnings enabled: javac -Xlint:allint a = 5; int b = a++; // b=5, a=6int a = 5; int b = ++a; // b=6, a=6int b = a; a++; or a++; int b = a; to avoid confusion| Operator Type | Symbols | Returns | Primary Use Case |
|---|---|---|---|
| Arithmetic | + - * / % ++ -- | A number (int, double, etc.) | Calculations — totals, scores, discounts |
| Relational | == != > < >= <= | boolean (true/false) | Comparisons — is X bigger than Y? |
| Logical | && || ! | boolean (true/false) | Chaining conditions — AND/OR/NOT logic |
| Assignment | = += -= *= /= %= | The assigned value | Storing or updating variable values |
| Ternary | ? : | Either of two values | Concise if-else for single value decisions |
| Bitwise | & | ^ ~ << >> >>> | An integer (int, long, etc.) | Low-level bit manipulation, flag operations, network protocols |
Key takeaways
Common mistakes to avoid
4 patternsUsing = instead of == in a comparison
if (x = 5) fails). But when using boolean variables, if (flag = true) sets flag to true and always enters the block.== for equality comparison. To prevent accidental assignment, consider Yoda conditions: if (5 == x) — if you accidentally write = Java will error because 5 is a literal, not a variable.Integer division silently discarding decimals
7 / 2 yields 3 instead of 3.5, causing downstream logic to misbehave. No error or warning is given.7.0 / 2 or (double) 7 / 2. For financial calculations, use BigDecimal.Confusing post-increment and pre-increment inside expressions
int b = a++ yields b = 5 when a = 5, but you expected 6 because you thought increment happens before assignment.a++; int b = a; to guarantee you get the incremented value. If you need the original value, place the variable first: int b = a; a++;Using & or | instead of && or || for logical conditions
&& and || for boolean logic to enable short-circuit evaluation. Reserve & and | for bitwise operations on integers.Interview Questions on This Topic
What is the difference between == and .equals() in Java, and when would using == to compare two String objects give you wrong answer?
s1 == s2 may be true if both refer to the same object from the String pool, but if created with new String("abc"), they will be different objects. Always use .equals() for String content comparison.What does the modulus operator (%) actually return, and can you give me a real-world use case for it beyond just checking if a number is even or odd?
index = (index + 1) % array.length for circular traversal. (2) Round-robin load balancing: serverIndex = requestCount % serverCount. (3) Extracting digits from a number: lastDigit = number % 10. (4) Converting seconds to time: minutes = seconds / 60; seconds = seconds % 60.What is the output of this code and why: int a = 5; int b = a++; System.out.println(a + ' ' + b); — Walk me through exactly what happens at each step.
Frequently Asked Questions
A single = is the assignment operator — it stores a value into a variable, like int age = 25. A double == is the equality comparison operator — it asks a yes/no question, like if (age == 25). Using = where you meant == is one of the most common beginner errors, so always double-check which one you need.
The % operator is called the modulus operator and it returns the remainder after integer division. For example, 10 % 3 gives 1 because 10 divided by 3 is 3 remainder 1. It's commonly used to check if a number is even (number % 2 == 0), to wrap a value within a range, or to distribute items evenly across groups.
Because both 7 and 2 are integers (int type), and when Java divides two integers the result is also an integer — the decimal part is simply discarded without rounding. To get 3.5, you need at least one value to be a double: write 7.0 / 2 or cast it with (double) 7 / 2. This is called integer division and it catches beginners off-guard frequently.
Use bitwise operators (&, |, ^) when you need to manipulate individual bits of an integer, such as storing multiple boolean flags in one int, implementing network protocol headers, or low-level cryptography. Use logical operators (&&, ||) for boolean conditions because they short-circuit and are more readable.
20+ years shipping production Java in banking & fintech. Drawn from code that ran under real load.
That's Java Basics. Mark it forged?
7 min read · try the examples if you haven't