Back to Blog
Java

Java XOR Operator: Syntax and Practical Uses

java xor operator: Explains the Java XOR operator (^) for booleans and integers, with practical patterns for bit toggling, unique-element detection, and common pitfalls.

bitwise-operatorsjavaboolean-logicbit-manipulationxor
Diagram showing XOR truth table and bitwise operation on integer values in Java

The java xor operator refers to the exclusive OR operator, written as ^ in Java. It works on both boolean values and integral types, but the behavior differs between the two. For booleans, ^ returns true when exactly one operand is true. For integers, it performs a bitwise operation that compares each bit position independently.

The Truth Table and Boolean Behavior

For boolean operands, XOR follows a simple rule: the result is true only when the two operands have different values.

LeftRightLeft ^ Right
truetruefalse
truefalsetrue
falsetruetrue
falsefalsefalse

This is the same rule used in logic circuits and is the reason XOR is sometimes called the "difference detector." A common use is validation logic where exactly one condition should hold:

boolean isAdmin = true; boolean isSuperUser = false; if (isAdmin ^ isSuperUser) { // exactly one elevated role is active }

This pattern is rare in production code because most developers find != more readable for boolean comparisons, but ^ is unambiguous when you need to enforce mutual exclusivity.

Bitwise XOR on Integral Types

When applied to byte, short, int, or long, ^ compares each bit position. A result bit is 1 when the corresponding bits of the operands differ, and 0 when they are the same.

int a = 0b1100; // 12 int b = 0b1010; // 10 int result = a ^ b; // 0b0110 = 6

Each bit pair is evaluated independently: 1^1=0, 1^0=1, 0^1=1, 0^0=0. The operation is commutative and associative, meaning the order of operands does not matter, and grouping does not matter either.

Toggling Bits in Flags and State

One of the most practical uses of XOR is toggling a specific bit without affecting others. Because x ^ 1 flips a bit and x ^ 0 leaves it unchanged, you can toggle a flag with a single operation.

int flags = 0b0010; // bit 1 is set flags ^= 0b0010; // bit 1 is now cleared flags ^= 0b0010; // bit 1 is set again

This works because XOR is its own inverse: applying the same value twice returns the original value. This property is the foundation of several algorithms, including the XOR swap trick and simple data masking.

Finding the Unique Element in an Array

A classic interview problem is finding the single element that appears once in an array where every other element appears twice. XOR solves this in linear time with constant space:

int findUnique(int[] values) { int result = 0; for (int value : values) { result ^= value; } return result; }

Because a ^ a == 0 and a ^ 0 == a, all paired elements cancel out, leaving only the unique value. This works for any integral type and does not require sorting or a hash map.

XOR Swap Without a Temporary Variable

The XOR swap exchanges two variables without a third variable:

int x = 5; int y = 9; x ^= y; y ^= x; x ^= y;

After these three operations, x holds 9 and y holds 5. The technique relies on the inverse property of XOR. It is rarely used in modern Java because the JIT compiler handles temporary-variable swaps efficiently, and the XOR version is harder to read. It remains useful in embedded or memory-constrained environments where register pressure matters.

Common Mistakes and Edge Cases

A frequent mistake is confusing ^ with exponentiation. Java has no exponent operator; Math.pow() is the correct method for powers. Writing 2 ^ 10 produces 8, not 1024, because it XORs the bit patterns of 2 and 10.

Another edge case involves negative numbers. XOR operates on the two's complement representation, so the sign bit participates in the operation. For example, -1 ^ 0 is -1, and -1 ^ 1 is -2. If you are working with unsigned semantics, use Integer.toUnsignedString() or work with long to avoid sign extension surprises.

Performance and Maintainability Considerations

XOR is a single machine instruction on virtually all modern CPUs, so its runtime cost is negligible compared to the surrounding logic. The real cost is maintainability: bitwise operations are compact but less readable than named constants. When using XOR for flags, define constants with descriptive names:

static final int READ = 0b001; static final int WRITE = 0b010; static final int EXECUTE = 0b100;

This keeps the intent clear while preserving the performance benefit of bit-level operations. In security-sensitive code, XOR is not encryption; it is reversible with the same key and should never be used for protecting data. Use it only for masking, checksums, or parity checks where its reversibility is acceptable.

java xor operator: Practical Usage and Code Examples | RYUSLOG DEV