Java Operators
Operators are special tokens that perform computations on values. Java inherits the C-family operator set: arithmetic, relational, logical, bitwise, assignment, and a few Java-specific extras. This tutorial is a complete tour, with examples you can paste and run.
Pay close attention to two rules throughout. First, every operator has a fixed precedence that decides grouping in the absence of parentheses. Second, most operators are left-associative, but assignment and the ternary are right-associative. When in doubt, add parentheses — clarity beats cleverness.
1. Arithmetic Operators
The five arithmetic operators work on every numeric type:
int sum = class="tok-num">10 + class="tok-num">5; class=class="tok-str">"tok-cmt">// class="tok-num">15
int diff = class="tok-num">10 - class="tok-num">5; class=class="tok-str">"tok-cmt">// class="tok-num">5
int prod = class="tok-num">10 * class="tok-num">5; class=class="tok-str">"tok-cmt">// class="tok-num">50
int quot = class="tok-num">10 / class="tok-num">3; class=class="tok-str">"tok-cmt">// class="tok-num">3 (integer division truncates)
int mod = class="tok-num">10 % class="tok-num">3; class=class="tok-str">"tok-cmt">// class="tok-num">1 (remainder)
double q = class="tok-num">10.0 / class="tok-num">3.0; class=class="tok-str">"tok-cmt">// class="tok-num">3.3333... (floating-point division)
Integer division truncates toward zero. The modulus operator % returns the remainder of integer division and works on floating-point too, though most teams avoid that.
2. Unary Operators
int x = class="tok-num">5;
int y = -x; class=class="tok-str">"tok-cmt">// -class="tok-num">5 (negation)
boolean ok = true;
boolean no = !ok; class=class="tok-str">"tok-cmt">// false (logical not)
int a = class="tok-num">10;
int b = a++; class=class="tok-str">"tok-cmt">// b = class="tok-num">10, then a becomes class="tok-num">11 (post-increment)
int c = ++a; class=class="tok-str">"tok-cmt">// a becomes class="tok-num">12, then c = class="tok-num">12 (pre-increment)
int bits = ~class="tok-num">0; class=class="tok-str">"tok-cmt">// -class="tok-num">1 (bitwise NOT flips every bit)
Pre-increment increments then returns the new value; post-increment returns the old value then increments. The same applies to decrement.
3. Relational Operators
Relational operators compare two values and return a boolean:
boolean a = class="tok-num">5 < class="tok-num">10; class=class="tok-str">"tok-cmt">// true
boolean b = class="tok-num">5 <= class="tok-num">5; class=class="tok-str">"tok-cmt">// true
boolean c = class="tok-num">10 > class="tok-num">5; class=class="tok-str">"tok-cmt">// true
boolean d = class="tok-num">10 >= class="tok-num">10; class=class="tok-str">"tok-cmt">// true
boolean e = class="tok-num">5 == class="tok-num">5; class=class="tok-str">"tok-cmt">// true
boolean f = class="tok-num">5 != class="tok-num">6; class=class="tok-str">"tok-cmt">// true
class=class="tok-str">"tok-cmt">// object equality: prefer .equals()
String s1 = new String("hi");
String s2 = new String("hi");
System.out.println(s1 == s2); class=class="tok-str">"tok-cmt">// false - different references
System.out.println(s1.equals(s2)); class=class="tok-str">"tok-cmt">// true - same content
For object equality, prefer .equals() over == — == compares references, not contents. Two distinct String objects with the same text will compare false with == but true with .equals().
4. Logical Operators
Logical operators combine boolean values:
boolean ok = true && false; class=class="tok-str">"tok-cmt">// false (AND, short-circuit)
boolean any = true || false; class=class="tok-str">"tok-cmt">// true (OR, short-circuit)
boolean both = true & false; class=class="tok-str">"tok-cmt">// false (AND, no short-circuit - evaluates both sides)
boolean either = true | false; class=class="tok-str">"tok-cmt">// true (OR, no short-circuit)
boolean xor = true ^ false; class=class="tok-str">"tok-cmt">// true (XOR)
class=class="tok-str">"tok-cmt">// short-circuit prevents NullPointerException
String s = null;
if (s != null && s.length() > class="tok-num">0) {
class=class="tok-str">"tok-cmt">// safe - length() is never called when s is null
}
The short-circuit forms && and || skip evaluating the right operand when the result is already determined. This is essential for null-safe checks: obj != null && obj.isValid() will not call isValid() on a null reference.
5. Bitwise Operators
Bitwise operators work on the binary representation of integer types:
int a = 0b1100; class=class="tok-str">"tok-cmt">// class="tok-num">12
int b = 0b1010; class=class="tok-str">"tok-cmt">// class="tok-num">10
int and = a & b; class=class="tok-str">"tok-cmt">// 0b1000 = class="tok-num">8
int or = a | b; class=class="tok-str">"tok-cmt">// 0b1110 = class="tok-num">14
int xor = a ^ b; class=class="tok-str">"tok-cmt">// 0b0110 = class="tok-num">6
int not = ~a; class=class="tok-str">"tok-cmt">// 0b...class="tok-num">001100 -> ...class="tok-num">110011 (two's complement = -class="tok-num">13)
int left = a << class="tok-num">2; class=class="tok-str">"tok-cmt">// 0b110000 = class="tok-num">48
int right = a >> class="tok-num">1; class=class="tok-str">"tok-cmt">// 0b0110 = class="tok-num">6 (signed)
int uright = a >>> class="tok-num">1; class=class="tok-str">"tok-cmt">// 0b0110 = class="tok-num">6 (unsigned)
These are uncommon in business logic but essential in low-level work: hashing, encoding, flags, and bit-packed data structures.
6. Assignment Operators
The simple assignment = stores the right-hand value into the left-hand variable. Compound assignments combine an operation with assignment:
int x = class="tok-num">10; class=class="tok-str">"tok-cmt">// simple assignment
x += class="tok-num">5; class=class="tok-str">"tok-cmt">// x = x + class="tok-num">5 = class="tok-num">15
x -= class="tok-num">3; class=class="tok-str">"tok-cmt">// x = x - class="tok-num">3 = class="tok-num">12
x *= class="tok-num">2; class=class="tok-str">"tok-cmt">// x = x * class="tok-num">2 = class="tok-num">24
x /= class="tok-num">5; class=class="tok-str">"tok-cmt">// x = x / class="tok-num">5 = class="tok-num">4
x %= class="tok-num">3; class=class="tok-str">"tok-cmt">// x = x % class="tok-num">3 = class="tok-num">1
x &= 0b1111; class=class="tok-str">"tok-cmt">// x = x & class="tok-num">15
x |= 0b10000; class=class="tok-str">"tok-cmt">// x = x | class="tok-num">16
x ^= class="tok-num">1; class=class="tok-str">"tok-cmt">// x = x ^ class="tok-num">1
x <<= class="tok-num">2; class=class="tok-str">"tok-cmt">// x = x << class="tok-num">2
x >>= class="tok-num">1; class=class="tok-str">"tok-cmt">// x = x >> class="tok-num">1
x >>>= class="tok-num">1; class=class="tok-str">"tok-cmt">// x = x >>> class="tok-num">1
Compound assignments automatically cast the result back to the left-hand type, so byte b = 0; b += 200; compiles even though b = b + 200 would not.
7. The Ternary Operator
The ternary is a one-line if/else. It returns one of two values depending on a boolean condition:
int age = class="tok-num">20;
String status = (age >= class="tok-num">18) ? "adult" : "minor";
class=class="tok-str">"tok-cmt">// status is "adult"
class=class="tok-str">"tok-cmt">// equivalent if/else
String s;
if (age >= class="tok-num">18) {
s = "adult";
} else {
s = "minor";
}
Use it for simple binary choices. Nested ternaries are hard to read — prefer a real if/else when you find yourself nesting more than once.
8. instanceof Operator
The instanceof operator tests whether an object is an instance of a class or interface:
Object obj = "Hello";
class=class="tok-str">"tok-cmt">// classic form - test and cast separately
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
class=class="tok-str">"tok-cmt">// pattern form (Java class="tok-num">16+) - test and bind in one
if (obj instanceof String s) {
System.out.println(s.length());
class=class="tok-str">"tok-cmt">// s is in scope here, of type String
}
Since Java 16, instanceof can bind the cast result to a pattern variable, eliminating the boilerplate cast that usually follows.
9. Precedence and Associativity
Operators group according to fixed precedence rules. Higher-precedence operators bind tighter. The full order, from highest to lowest, is:
- Postfix:
expr++ expr-- - Unary:
++expr --expr +expr -expr ~ ! (cast) new - Multiplicative:
* / % - Additive:
+ - - Shift:
<< >> >>> - Relational:
< <= > >= instanceof - Equality:
== != - Bitwise AND:
& - Bitwise XOR:
^ - Bitwise OR:
| - Logical AND:
&& - Logical OR:
|| - Ternary:
?: - Assignment:
= += -= *= /= %= &= |= ^= <<= >>= >>>=
Even if you remember all of precedence, the next reader may not. When mixing operators, parenthesise for clarity: (a + b) * c is universally understood, while a + b * c forces the reader to recall precedence.
Exercises
- Compute and print the area of a circle with radius 5 using
Math.PI. - Use the ternary to print “adult” or “minor” based on an
int age. - Write a null-safe check using
&&short-circuiting on a String reference. - Swap two
intvariables using only the XOR operator^— the classic interview trick.