Operators and Expressions
|
This section documents the current Java release line, with Java 25 LTS as the reference point (no specific patch version is pinned), as published at the Java developer portal, the Java Tutorials, and the Java SE API specification — which are the references these pages are written and verified against. This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. This section’s bibliography lists the reference material consulted while preparing these pages. |
An expression combines values, variables, and method calls with operators to produce a result. This page follows dev.java "Using Operators", the Java Tutorials "Operators" lesson, and JLS chapter 15, "Expressions".
Arithmetic, Unary, and Increment/Decrement
int sum = 7 + 3; // 10
int diff = 7 - 3; // 4
int prod = 7 * 3; // 21
int quot = 7 / 3; // 2 -- integer division truncates toward zero
int rem = 7 % 3; // 1 -- remainder; its sign follows the dividend: -7 % 3 == -1
double d = 7.0 / 3; // 2.3333333333333335 -- one double operand => floating-point division
int neg = -sum; // unary minus
int pos = +sum; // unary plus (a no-op, kept for symmetry)
String a = "n = " + 1 + 2; // "n = 12" -- + is concatenation once a String is involved
String b = "n = " + (1 + 2); // "n = 3"
int n = 5;
int post = n++; // post-increment: post == 5, then n == 6
int pre = ++n; // pre-increment: n == 7, then pre == 7
/ between two integers is integer division (truncates toward zero); % is the remainder, whose
result takes the sign of the left operand — not a mathematical modulo. Mixing an integer with a
floating-point operand promotes both to floating point (numeric promotion,
JLS 5.6). Integer / 0 and
% 0 throw
ArithmeticException;
floating-point division by zero yields Infinity or NaN instead. + is overloaded for
String
concatenation (details on Strings and Text).
Relational, Logical, and Conditional
boolean lt = 3 < 5; // < <= > >= -> boolean
boolean eq = 3 == 3; // == !=
boolean ne = 3 != 4;
// && and || short-circuit: the right operand is skipped once the result is known
String name = null;
if (name != null && name.length() > 0) { // no NullPointerException: length() is never reached
// ...
}
boolean ready = cached() || recompute(); // recompute() runs only if cached() is false
boolean not = !ready; // logical negation
// & and | also work on boolean, but ALWAYS evaluate both sides -- rarely what you want
boolean both = check(1) & check(2);
// the conditional (ternary) operator: condition ? whenTrue : whenFalse
int max = (lt) ? 5 : 3;
String label = (name == null) ? "anonymous" : name;
== on reference types compares identity, not contents — use equals for objects (see
Classes and Objects and
Strings and Text). && and || short-circuit and are what you
almost always want; the bitwise & / | / ^ accept boolean operands too but never short-circuit.
The conditional operator is Java’s only ternary operator, is an expression (not a statement), and its
two branches must have compatible types. See
JLS 15.25.
Bitwise, Shift, and Assignment
int x = 0b1100; // 12
int y = 0b1010; // 10
int and = x & y; // 0b1000 (8)
int or = x | y; // 0b1110 (14)
int xor = x ^ y; // 0b0110 (6)
int notX = ~x; // -13 -- two's-complement bitwise NOT
int left = 1 << 4; // 16 -- left shift, zero-filled
int right = -8 >> 1; // -4 -- signed (arithmetic) right shift, keeps the sign bit
int uns = -8 >>> 28; // 15 -- unsigned right shift, zero-filled; there is no <<<
// assignment is itself an expression that yields the assigned value
int p, q;
p = q = 0; // q = 0 evaluates to 0, which is then assigned to p
// compound assignment: v op= e means v = (T)(v op e) -- note the implicit cast
int m = 10;
m += 5; // 15
m *= 2; // 30
m >>= 1; // 15
byte bb = 10;
bb += 300; // compiles: the implicit (byte) cast wraps the result to 54
Bitwise and shift operators act on int and long (narrower operands promote to int first). >>
keeps the sign bit, >>> shifts in zeros, and the shift distance is taken modulo 32 for int or 64
for long. Compound assignment performs a silent narrowing cast, which can hide truncation. See
the Java Tutorials "Bitwise and Bit
Shift Operators" page.
instanceof, Precedence, and Evaluation Order
Object o = "hello";
// classic form: test, then cast
if (o instanceof String) {
String s = (String) o;
System.out.println(s.length());
}
// instanceof type pattern: tests and binds in one step
if (o instanceof String s) {
System.out.println(s.length());
}
// flow scoping lets the binding be used in the same condition
if (o instanceof String s && !s.isBlank()) {
System.out.println(s.strip());
}
instanceof tests the runtime type and is always false for null. The pattern form
(o instanceof String s) is the entry point to pattern matching — see
Pattern Matching.
Java evaluates operands left to right: the left operand (including its side effects) is fully evaluated before the right, and method arguments are evaluated left to right before the call. Only then are operators applied, according to precedence.
int[] arr = new int[3];
int i = 0;
arr[i] = i = 2; // the index i is read as 0 first; arr[0] is assigned, then i becomes 2
// result: arr == {2, 0, 0}, i == 2
int r = first() + second() * 2; // call first(), then second(), then '*', then '+'
Precedence, from highest to lowest (full grammar in JLS 15):
group operators associativity
--------------------------------------------------------------------------------
postfix expr++ expr-- left to right
unary ++expr --expr +expr -expr ~ ! right to left
cast / new (type)expr new right to left
multiplicative * / % left to right
additive + - (and String +) left to right
shift << >> >>> left to right
relational < <= > >= instanceof left to right
equality == != left to right
bitwise AND & left to right
bitwise XOR ^ left to right
bitwise OR | left to right
logical AND && left to right
logical OR || left to right
conditional ? : right to left
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>= right to left
When precedence is not obvious to a reader, add parentheses — they cost nothing and document intent.
See Also
-
Primitive Types and Variables — the operand types, casts, and numeric promotion.
-
Control Flow —
if, loops, andswitchexpressions built from these expressions. -
Pattern Matching —
instanceofandswitchtype patterns. -
Strings and Text —
==versusequalsand+concatenation.