Java's operators are grouped by what they do: arithmetic, assignment, comparison, logical, bitwise and a couple of oddities. The syntax is familiar, but three of them behave in ways that will surprise you at least once — integer division, the short-circuiting logical operators, and + on strings.
What are the arithmetic operators?
Addition, subtraction, multiplication, division and remainder, plus a unary minus. The one to internalise is the division: two integers divide to an integer.
int a = 17;
int b = 5;
System.out.println(a + b); // 22
System.out.println(a - b); // 12
System.out.println(a * b); // 85
System.out.println(a / b); // 3 — integer division
System.out.println(a % b); // 2 — the remainder
System.out.println((double) a / b); // 3.4
When you want a fractional result, promote one operand to double before dividing. Casting the result afterwards is too late — the precision is already gone.
What about the compound assignment operators?
Java has a shorthand for the common "compute then store" pattern.
int total = 100;
total += 25; // total = total + 25
total -= 10;
total *= 2;
total /= 4;
total %= 7;
System.out.println(total);
The compound form is not only shorter, it is also safer with narrower types, because the compiler checks that the result still fits. It also reads well with strings: message += " more"; is clearer than message = message + " more";.
What is the difference between ++ and --?
Both add one and subtract one. The interesting part is when the change happens relative to the surrounding expression, and the difference only shows up if you use the result of the expression.
int a = 5;
int b = a++; // b gets 5, then a becomes 6
int c = 5;
int d = ++c; // c becomes 6 first, then d gets 6
System.out.println(a + " " + b + " " + c + " " + d); // 6 5 6 6
As a rule, never use ++ or -- inside a larger expression. The two forms are too similar to read reliably, and the code is not shorter in a way that pays for the confusion. As a statement on its own, count++; is fine.
Which comparison operators exist?
Six of them: ==, !=, <, >, <= and >=. Two rules catch people out.
String a = "hello";
String b = new String("hello");
System.out.println(a == b); // false — different objects
System.out.println(a.equals(b)); // true — same content
First, == on objects compares references, so two equal-looking strings built differently are not ==. Use equals to compare content. Second, and more subtle: == on numeric types compares values, but if one side is a double the comparison is done as floating point, so 0.1 + 0.2 == 0.3 is false. Comparing floating point for equality needs a tolerance.
What do the logical operators do?
&& and || combine booleans, and they short-circuit: the right-hand side is not evaluated at all when the left-hand side already decides the answer. ! negates, and ^ is exclusive-or on booleans.
String name = null;
if (name != null && !name.isEmpty()) {
System.out.println(name.length());
}
// the second test never runs, so this is safe
Short-circuiting is what makes the null check above safe. It is also the difference between a working program and a crash: a != null && a.length() > 0 works, while a.length() > 0 && a != null throws when a is null. The bitwise forms & and | evaluate both sides, so they are reserved for flags.
What is the ternary operator?
The conditional operator takes three operands and returns one of two values. It is an expression, so it can be used where a statement could not — inside a return, an argument list, or an assignment.
int age = 20;
String status = age >= 18 ? "adult" : "minor";
System.out.println(status);
System.out.println(age >= 18 ? "can vote" : "cannot vote");
Use it for a genuine either-or between two values. The moment it grows nested ternaries, switch to an if statement — nested ternaries are famously hard to read, and every maintainer who meets one wishes it had been written differently.
What are the bitwise operators for?
They work on the individual bits of integral values. Most of the time you will not need them, but three uses come up often: testing flags, shifting, and masking out part of a value.
int flags = 0;
flags |= 1 << 0; // set bit 0
flags |= 1 << 2; // set bit 2
System.out.println(flags); // 5
System.out.println((flags & (1 << 0)) != 0); // true — bit 0 is set
System.out.println((flags & (1 << 1)) != 0); // false
System.out.println(flags >> 1); // 2 — shift right
System.out.println(-8 >>> 1); // 2147483644 — unsigned shift
Bit flags are how systems that need many independent booleans avoid a constructor with fifteen parameters. Shifts are how you multiply and divide by powers of two, and mask the low bits of an identifier. The rest of the time, ordinary arithmetic and comparison are clearer.
What order do the operators apply in?
Java follows a fixed precedence, and it is worth memorising the part you use daily: multiplication and division bind tighter than addition and subtraction; comparisons bind tighter than the logical operators; and && binds tighter than ||. Where the precedence is not obvious, parentheses are not optional.
System.out.println(2 + 3 * 4); // 14
System.out.println((2 + 3) * 4); // 20
System.out.println(1 + 2 < 4 && 5 > 3); // true
System.out.println(true || false && false); // true — && binds tighter
Assignment sits below everything else and is right-associative, so a = b = c assigns to b and then that result to a. The classic trap is the missing-brace bug: a for loop without braces runs only the first statement, so an extra line inside the loop body silently does nothing at all.
Quick reference
- Integer division truncates; promote before dividing if you want a fraction.
- Compound assignment is shorter and checks overflow at compile time.
- Never use
++inside a larger expression. ==on objects compares references — useequals.&&and||short-circuit, which makes null checks safe.- The ternary operator is an expression, but nested ternaries hurt readability.
Try it yourself: write a program that reads a number and prints whether it is even, positive, and divisible by three, using only comparisons and logical operators. Then use bit flags to hold the three results in one integer and print which flags are set. Finally, compare two equal-looking strings with both == and equals and explain the difference in one sentence.