Skip to main content
Java beginner Lesson 4 of 58

Operators in Java

Complete guide to Java operators — arithmetic, relational, bitwise, shift, logical, ternary, instanceof, and operator precedence.

Arithmetic Operators

The basic math operators work on numeric types (int, long, double, etc.):

public class ArithmeticDemo {
    public static void main(String[] args) {
        int a = 17, b = 5;

        System.out.println(a + b);  // 22  — addition
        System.out.println(a - b);  // 12  — subtraction
        System.out.println(a * b);  // 85  — multiplication
        System.out.println(a / b);  // 3   — integer division (truncates)
        System.out.println(a % b);  // 2   — modulo (remainder)

        // Floating-point division
        System.out.println(17.0 / 5);   // 3.4
        System.out.println((double) a / b); // 3.4 — cast one operand

        // Integer overflow wraps around silently
        int max = Integer.MAX_VALUE; // 2_147_483_647
        System.out.println(max + 1);     // -2_147_483_648 (wraps!)
        // Use long or Math.addExact() to detect overflow:
        // Math.addExact(max, 1); // throws ArithmeticException
    }
}

Increment and Decrement

int x = 10;

// Post-increment: use then increment
System.out.println(x++); // 10 — prints x, then x becomes 11
System.out.println(x);   // 11

// Pre-increment: increment then use
System.out.println(++x); // 12 — x becomes 12, then prints
System.out.println(x);   // 12

// Same logic for decrement (--)
int y = 5;
System.out.println(y--); // 5
System.out.println(y);   // 4

Compound Assignment Operators

int n = 20;
n += 5;  // n = n + 5  → 25
n -= 3;  // n = n - 3  → 22
n *= 2;  // n = n * 2  → 44
n /= 4;  // n = n / 4  → 11
n %= 3;  // n = n % 3  → 2

Relational Operators

Relational operators return boolean:

int a = 10, b = 20;

System.out.println(a == b);  // false — equal
System.out.println(a != b);  // true  — not equal
System.out.println(a <  b);  // true  — less than
System.out.println(a >  b);  // false — greater than
System.out.println(a <= b);  // true  — less than or equal
System.out.println(a >= b);  // false — greater than or equal

Logical Operators

boolean sunny = true;
boolean warm  = false;

// && — AND: both must be true
System.out.println(sunny && warm);  // false

// || — OR: at least one must be true
System.out.println(sunny || warm);  // true

// ! — NOT: flips the value
System.out.println(!sunny);         // false

// Short-circuit evaluation:
// && stops at the first false; || stops at the first true
int[] arr = null;
// Safe because arr != null is checked first
if (arr != null && arr.length > 0) {
    System.out.println(arr[0]);
}

Bitwise Operators

Bitwise operators work directly on the binary representation of integers:

public class BitwiseDemo {
    public static void main(String[] args) {
        int a = 0b1010; // 10
        int b = 0b1100; // 12

        // & AND — bit is 1 only if both bits are 1
        System.out.println(Integer.toBinaryString(a & b)); // 1000 = 8

        // | OR — bit is 1 if at least one bit is 1
        System.out.println(Integer.toBinaryString(a | b)); // 1110 = 14

        // ^ XOR — bit is 1 if the bits differ
        System.out.println(Integer.toBinaryString(a ^ b)); // 0110 = 6

        // ~ NOT — flips all bits (one's complement)
        System.out.println(~a); // -11 (two's complement)
    }
}

Common Bitwise Patterns

// Check if a number is even (last bit is 0)
boolean isEven = (n & 1) == 0;

// Check if the k-th bit is set (0-indexed from right)
boolean isSet = (n & (1 << k)) != 0;

// Set the k-th bit
int withBitSet = n | (1 << k);

// Clear the k-th bit
int withBitCleared = n & ~(1 << k);

// Toggle the k-th bit
int toggled = n ^ (1 << k);

// Fast multiply/divide by powers of 2
int doubled   = n << 1; // n * 2
int halved    = n >> 1; // n / 2
int times8    = n << 3; // n * 8

Shift Operators

int n = 8; // binary: 0000_1000

// << left shift — multiply by 2^k (fills right with 0s)
System.out.println(n << 1); // 16  (8 * 2)
System.out.println(n << 3); // 64  (8 * 8)

// >> signed right shift — divide by 2^k (preserves sign bit)
System.out.println(n >> 1);  // 4   (8 / 2)
System.out.println(-8 >> 1); // -4  (sign preserved)

// >>> unsigned right shift — always fills with 0 from left
System.out.println(-8 >>> 1); // 2147483644 (large positive)

// Extracting bytes from an int (common in network/file I/O)
int value = 0xABCD1234;
byte b0 = (byte) (value & 0xFF);          // least significant byte: 0x34
byte b1 = (byte) ((value >> 8)  & 0xFF);  // 0x12
byte b2 = (byte) ((value >> 16) & 0xFF);  // 0xCD
byte b3 = (byte) ((value >> 24) & 0xFF);  // 0xAB

Ternary Operator

The ternary condition ? valueIfTrue : valueIfFalse is a compact if-expression:

int score = 73;

// Equivalent to if/else, but produces a value
String grade = score >= 90 ? "A"
             : score >= 80 ? "B"
             : score >= 70 ? "C"
             : score >= 60 ? "D"
             : "F";

System.out.println(grade); // C

// Ternary inline in string formatting
int items = 3;
String label = items + " " + (items == 1 ? "item" : "items");
System.out.println(label); // 3 items

// Use for selecting between two values, not for complex logic
int max = (a > b) ? a : b;

instanceof — Type Check

Traditional (Java 1+)

Object obj = "Hello, Java!";

if (obj instanceof String) {
    String s = (String) obj; // manual cast required
    System.out.println(s.length()); // 12
}

Pattern Matching instanceof (Java 16+)

Object obj = "Hello, Java!";

// Type test + binding in one expression — no manual cast
if (obj instanceof String s) {
    System.out.println(s.length()); // 12
}

// Works great in switch (Java 21+)
static String describe(Object obj) {
    return switch (obj) {
        case Integer i  -> "int: " + i;
        case Double  d  -> "double: " + d;
        case String  s  -> "string of length " + s.length();
        case int[]   a  -> "int array of length " + a.length;
        case null       -> "null";
        default         -> "other: " + obj.getClass().getSimpleName();
    };
}

Operator Precedence

Higher precedence operators bind tighter. When in doubt, use parentheses for clarity.

PrecedenceOperators
1 (highest)++ -- (postfix), () [] .
2++ -- (prefix), + - (unary), ~ !
3* / %
4+ -
5<< >> >>>
6< > <= >= instanceof
7== !=
8&
9^
10|
11&&
12||
13?: (ternary)
14 (lowest)= += -= *= /= %= etc.
// Surprises from precedence
System.out.println(2 + 3 * 4);     // 14, not 20 — * before +
System.out.println(1 + 2 + "3");   // "33" — left-to-right, int+int+"3"
System.out.println("1" + 2 + 3);   // "123" — string concat once string appears
System.out.println(true || false && false); // true — && before ||

// When in doubt, parenthesise
System.out.println((2 + 3) * 4);   // 20

Practical Examples

Flag manipulation with bitwise ops

// Permission flags as bit constants
static final int READ    = 0b001; // 1
static final int WRITE   = 0b010; // 2
static final int EXECUTE = 0b100; // 4

int permissions = READ | WRITE; // 3 — has read and write

// Check permission
boolean canRead    = (permissions & READ)    != 0; // true
boolean canExecute = (permissions & EXECUTE) != 0; // false

// Grant execute permission
permissions |= EXECUTE; // 7 — now all three

// Revoke write permission
permissions &= ~WRITE; // 5 — READ | EXECUTE

Safe division with ternary

static double safeDivide(double a, double b) {
    return b != 0 ? a / b : 0.0;
}

System.out.println(safeDivide(10, 3));  // 3.333...
System.out.println(safeDivide(10, 0)); // 0.0

Frequently Asked Questions

What is the difference between == and .equals() in Java?
== compares references (memory addresses) for objects, and values for primitives. .equals() compares content. For strings, 'hello' == 'hello' may be true due to string interning, but new String('hello') == new String('hello') is false. Always use .equals() to compare object content.
What does the >>> operator do?
>>> is the unsigned right shift operator. Unlike >>, it always fills the leftmost bits with 0, even for negative numbers. This is useful when treating int values as bit patterns regardless of sign.
When should I use the ternary operator?
Use the ternary for simple, single-value assignments where both branches are short expressions: String label = count == 1 ? 'item' : 'items'. Avoid nesting ternaries or using them for side effects — an if/else is clearer in those cases.
What does instanceof do in Java 16+?
The pattern-matching instanceof (Java 16+) tests the type AND binds a variable in one step: if (obj instanceof String s) { ... use s ... }. This eliminates the manual cast that was needed before Java 16.