00:00

Unary Operators in Java – Explained with Examples

Last updated: 8 min read

Unary operators work on a single operand. They change a value's sign, add or subtract one, invert a boolean, or flip every bit. The increment (++) and decrement (--) operators are among the most used operators in Java, especially in loops, and the difference between their prefix and postfix forms is a favourite interview topic.

This tutorial covers every unary operator with examples, explains pre- and post-increment step by step, and shows the traps to avoid.

1. Java's Unary Operators

Unary operators in Java
OperatorNameExampleEffect
+Unary plus+xReturns the value (promotes small types to int)
-Unary minus-xNegates the value
++Increment++x, x++Adds 1 to the variable
--Decrement--x, x--Subtracts 1 from the variable
!Logical NOT!doneInverts a boolean
~Bitwise complement~xFlips every bit; equals -x - 1
UnaryBasics.java
public class UnaryBasics {
    public static void main(String[] args) {
        int x = 10;
        System.out.println("+x  = " + (+x));      // unary plus: no change
        System.out.println("-x  = " + (-x));      // unary minus: negation

        int count = 5;
        count++;                                  // increment by 1
        System.out.println("count++ -> " + count);
        count--;                                  // decrement by 1
        System.out.println("count-- -> " + count);

        boolean loggedIn = false;
        System.out.println("!loggedIn = " + !loggedIn);   // logical NOT

        System.out.println("~10 = " + (~10));      // bitwise complement: -(10) - 1
    }
}
Output
+x  = 10
-x  = -10
count++ -> 6
count-- -> 5
!loggedIn = true
~10 = -11

2. Pre-Increment vs Post-Increment

Both forms add one to the variable. The difference is which value the expression returns:

  • Prefix ++x: increment first, then return the new value.
  • Postfix x++: return the old value, then increment.

The same applies to --x and x--. When the increment is a statement on its own (count++;), both forms behave identically.

PrePostIncrement.java
public class PrePostIncrement {
    public static void main(String[] args) {
        int a = 5;
        int b = ++a;              // pre-increment: add first, then use
        System.out.println("b = ++a  -> a=" + a + ", b=" + b);

        int c = 5;
        int d = c++;              // post-increment: use first, then add
        System.out.println("d = c++  -> c=" + c + ", d=" + d);

        int i = 1;
        int result = i++ + ++i;   // 1 (i becomes 2) + 3 (i becomes 3)
        System.out.println("i++ + ++i = " + result + ", i=" + i);

        int x = 10;
        x = x++;                  // classic trap: x stays 10
        System.out.println("x = x++  -> x=" + x);

        int[] arr = {10, 20, 30};
        int idx = 0;
        System.out.println("arr[idx++] = " + arr[idx++] + ", idx now " + idx);
    }
}
Output
b = ++a  -> a=6, b=6
d = c++  -> c=6, d=5
i++ + ++i = 4, i=3
x = x++  -> x=10
arr[idx++] = 10, idx now 1

Step by step: i++ + ++i

  1. i starts at 1. i++ returns 1 and sets i to 2.
  2. ++i sets i to 3 and returns 3.
  3. 1 + 3 = 4, and i ends at 3.

Why x = x++ leaves x unchanged

  1. x++ saves the old value 10 and increments x to 11.
  2. The assignment then stores the saved value 10 back into x.

Java evaluates operands strictly left to right, so these results are well defined (unlike in C, where they can be undefined). Still, avoid writing such code: use x++; or x += 1; on its own line.

3. Increment and Decrement on Other Types

++ and -- work on every numeric type and on char, and they include an implicit cast, just like +=:

IncrementTypes.java
public class IncrementTypes {
    public static void main(String[] args) {
        byte b = 127;
        b++;                       // ++ includes a cast: wraps to -128
        System.out.println("byte 127++ = " + b);

        char letter = 'x';
        letter++;
        System.out.println("'x'++ = " + letter);

        double price = 9.5;
        price++;
        System.out.println("9.5++ = " + price);

        // Loop counters are the most common use of ++ and --
        StringBuilder sb = new StringBuilder();
        for (int i = 3; i > 0; i--) sb.append(i).append(' ');
        System.out.println("countdown: " + sb + "go!");
    }
}
Output
byte 127++ = -128
'x'++ = y
9.5++ = 10.5
countdown: 3 2 1 go!
  • Incrementing a byte at 127 wraps silently to −128.
  • On a char, ++ moves to the next Unicode character.
  • On a double, it adds exactly 1.0.
  • ++ and -- need a variable: 5++ or (a + b)++ do not compile, and final variables cannot be incremented.

4. Logical NOT (!)

! turns true into false and vice versa. It works only on booleans and is used to negate conditions: if (!list.isEmpty()), while (!found). Name boolean variables positively (isValid, not isNotValid) so that ! reads naturally.

5. Bitwise Complement (~)

~ flips every bit of an integer. Because Java stores negative numbers in two's complement, ~x always equals -x - 1, so ~10 is -11. It is used with masks, for example flags &= ~WRITE to clear a bit. See Bitwise Operators.

6. Unary Minus and Overflow

Negating the smallest int overflows: -Integer.MIN_VALUE is still Integer.MIN_VALUE, because +2,147,483,648 does not fit in an int. Math.negateExact() throws an exception instead, and Math.abs() has the same edge case.

7. Precedence

Postfix x++ and x-- have the highest precedence of all operators, followed by the prefix unary operators (++x, --x, +, -, !, ~ and casts), which group right to left. So -x++ means -(x++), and !a && b means (!a) && b.

8. Increment Is Not Atomic

count++ looks like one step but is really three: read, add one, write back. If two threads do it at the same time, updates can be lost. Use AtomicInteger.incrementAndGet(), LongAdder or synchronization for shared counters.

9. Summary

  • Unary operators take one operand: +, -, ++, --, ! and ~.
  • ++x returns the new value; x++ returns the old value. As standalone statements they are the same.
  • ++ and -- include an implicit cast and can overflow silently.
  • ! inverts booleans; ~ flips bits and equals -x - 1.
  • Avoid expressions like x = x++, and use atomic classes for shared counters.

Related Tutorials