Java Operators

BEGINNER ~8 min read Tutorial

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:

java
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

java
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:

java
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:

java
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:

java
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:

java
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:

java
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:

java
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:

  1. Postfix: expr++ expr--
  2. Unary: ++expr --expr +expr -expr ~ ! (cast) new
  3. Multiplicative: * / %
  4. Additive: + -
  5. Shift: << >> >>>
  6. Relational: < <= > >= instanceof
  7. Equality: == !=
  8. Bitwise AND: &
  9. Bitwise XOR: ^
  10. Bitwise OR: |
  11. Logical AND: &&
  12. Logical OR: ||
  13. Ternary: ?:
  14. Assignment: = += -= *= /= %= &= |= ^= <<= >>= >>>=
Use parentheses

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

  1. Compute and print the area of a circle with radius 5 using Math.PI.
  2. Use the ternary to print “adult” or “minor” based on an int age.
  3. Write a null-safe check using && short-circuiting on a String reference.
  4. Swap two int variables using only the XOR operator ^ — the classic interview trick.