Operators are the symbols that do work on values: + adds, == compares, && combines conditions. An expression is any combination of values, variables, operators and method calls that produces a value, such as price * quantity or items.size() > 0. This guide covers every operator group with examples, the precedence rules, and the traps that show up in interviews and test code.
Operator Groups at a Glance
| Group | Operators | Example |
|---|---|---|
| Arithmetic | + - * / % | total = price * qty |
| Unary | + - ++ -- ! | count++, !isVisible |
| Assignment | = += -= *= /= %= and others | retries += 1 |
| Relational | == != > < >= <= | status == 200 |
| Logical | && || ! | isDisplayed && isEnabled |
| Bitwise and shift | & | ^ ~ << >> >>> | flags & MASK |
| Ternary | ? : | String b = headless ? "chrome-headless" : "chrome"; |
| Type comparison | instanceof | if (driver instanceof TakesScreenshot ts) |
Arithmetic Operators and Their Traps
int a = 7, b = 2;
System.out.println(a / b); // 3 integer division drops the fraction
System.out.println(a / 2.0); // 3.5 one double operand makes it floating-point
System.out.println(a % b); // 1 remainder
System.out.println(-7 % 2); // -1 the sign follows the left operand
System.out.println(0.1 + 0.2); // 0.30000000000000004 use BigDecimal for money
Integer overflow is silent: Integer.MAX_VALUE + 1 becomes a large negative number without an error. Use long or Math.addExact when values can grow.
Increment and Decrement: Prefix vs Postfix
int i = 5;
int x = i++; // x = 5, then i becomes 6 (postfix: use, then increment)
int y = ++i; // i becomes 7, then y = 7 (prefix: increment, then use)
On its own line (i++;) there's no difference. Avoid mixing them into bigger expressions; code like i = i++ + ++i is legal but unreadable.
Relational Operators and the == Trap
For primitives, == compares values. For objects it compares references, that is whether both variables point to the same object. Always compare strings with equals():
String expected = "Products";
String actual = driver.findElement(By.className("title")).getText();
System.out.println(actual == expected); // false: different String objects
System.out.println(actual.equals(expected)); // true
Logical Operators and Short-Circuiting
&& and || short-circuit: the right side runs only if it can change the result. This is how null checks work safely:
if (element != null && element.isDisplayed()) { ... } // isDisplayed() never runs on null
The single & and | also work on booleans but always evaluate both sides, so a null check with & would still throw NullPointerException.
Assignment and Compound Assignment
Compound operators like += include a hidden cast, which surprises people:
byte b = 10;
b += 5; // compiles: same as b = (byte) (b + 5)
b = b + 5; // compile error: b + 5 is an int
The Ternary Operator
condition ? valueIfTrue : valueIfFalse is an expression, so it can be assigned or returned. Keep it to simple choices; nested ternaries are hard to read.
String env = System.getProperty("env");
String baseUrl = (env == null) ? "https://qa.example.com" : "https://" + env + ".example.com";
String Concatenation and Evaluation Order
+ means string concatenation as soon as one operand is a String, and it's evaluated left to right:
System.out.println(1 + 2 + "3"); // "33" (1 + 2 = 3, then "3" + "3")
System.out.println("1" + 2 + 3); // "123" (string from the start)
System.out.println("1" + (2 + 3)); // "15" (brackets first)
instanceof and Pattern Matching
instanceof checks an object's type. Since Java 16 it can also declare a variable, removing the cast:
if (driver instanceof TakesScreenshot ts) {
byte[] png = ts.getScreenshotAs(OutputType.BYTES);
}
Operator Precedence
When an expression has several operators, higher-precedence ones are applied first. From highest to lowest:
| Level | Operators | Associativity |
|---|---|---|
| 1 | Postfix expr++ expr-- | Left to right |
| 2 | Unary ++expr --expr +expr -expr ~ !, casts | Right to left |
| 3 | Multiplicative * / % | Left to right |
| 4 | Additive + - | Left to right |
| 5 | Shift << >> >>> | Left to right |
| 6 | Relational < > <= >= instanceof | Left to right |
| 7 | Equality == != | Left to right |
| 8–10 | Bitwise &, then ^, then | | Left to right |
| 11–12 | Logical &&, then || | Left to right |
| 13 | Ternary ? : | Right to left |
| 14 | Assignment = += -= *= /= etc. | Right to left |
So a + b * c multiplies first, and x > 0 && y > 0 || z groups as (x > 0 && y > 0) || z. When in doubt, add brackets: they cost nothing and make intent obvious.
Expressions vs Statements
An expression produces a value (a + b, list.isEmpty()). A statement is a complete instruction ending in a semicolon or block (int total = a + b;, an if). Some expressions can stand alone as statements: assignments, ++/--, method calls and object creation. Control flow is covered in Control Flow Statements in Java.
FAQs
What is the difference between = and == in Java?
= assigns a value to a variable; == compares two values (or two references, for objects) and returns a boolean.
What is the difference between && and & in Java?
Both perform logical AND on booleans, but && short-circuits: if the left side is false, the right side isn't evaluated. & always evaluates both sides and is also a bitwise operator on integers.
Why does 5 / 2 give 2 in Java?
Both operands are integers, so Java performs integer division and drops the fractional part. Make one operand a double (5 / 2.0) to get 2.5.
What is the output of 1 + 2 + "3" in Java?
"33". Evaluation is left to right: 1 + 2 is 3, then 3 + "3" is string concatenation.