W3docs

Java Bitwise Operators

Manipulate individual bits in Java with &, |, ^, ~, <<, >>, and >>> bitwise operators.

Most Java code doesn't touch individual bits. But every now and then — packing flags into one int, reading a binary file format, computing a hash, working with permission bitmasks — you'll need to manipulate values at the bit level. Java's bitwise operators are the C-style set: &, |, ^, ~, and the three shifts.

The operators

OperatorNameWhat it does
&ANDbit is 1 only if both bits are 1
|ORbit is 1 if either bit is 1
^XORbit is 1 if the two bits differ
~NOT (complement)flips every bit
<<left shiftshifts bits left, fills with 0 on the right
>>signed right shiftshifts right, fills with the sign bit on left
>>>unsigned right shiftshifts right, fills with 0 on the left

All operate on int and long operands. byte, short, and char are promoted to int first.

Binary literals (0b...) make the bit patterns easy to see:

int a = 0b1100;   // 12
int b = 0b1010;   // 10

System.out.println(Integer.toBinaryString(a & b));   // 1000  (8)
System.out.println(Integer.toBinaryString(a | b));   // 1110  (14)
System.out.println(Integer.toBinaryString(a ^ b));   // 0110  (6)

NOT — ~

~ flips every bit, including the sign bit. For 32-bit int, that's two's complement: ~x equals -x - 1:

System.out.println(~0);    // -1
System.out.println(~5);    // -6
System.out.println(~-1);   // 0

Shifts

<< shifts left, multiplying by powers of 2:

System.out.println(1 << 0);   // 1
System.out.println(1 << 1);   // 2
System.out.println(1 << 4);   // 16

>> shifts right, preserving the sign — useful for dividing signed integers:

System.out.println(16 >> 2);   // 4
System.out.println(-16 >> 2);  // -4   — sign extended

>>> shifts right and always fills with zero — meaningful when you're treating an int as unsigned bits:

System.out.println(-1 >>> 28);  // 15
System.out.println(-1 >> 28);   // -1

Practical uses

Flag bitmasks

Pack several yes/no flags into a single int:

final int READ    = 1 << 0;  // 0001
final int WRITE   = 1 << 1;  // 0010
final int EXECUTE = 1 << 2;  // 0100

int perms = READ | WRITE;             // set both

boolean canRead    = (perms & READ) != 0;     // true
boolean canExecute = (perms & EXECUTE) != 0;  // false

perms |= EXECUTE;       // grant execute
perms &= ~WRITE;        // revoke write
perms ^= READ;          // toggle read

This is the same idea as Unix file permissions.

Multiplying or dividing by powers of 2

x << n is x * 2ⁿ; x >> n is x / 2ⁿ (for non-negative x):

int doubled = x << 1;
int halved  = x >> 1;

The compiler will usually optimise plain multiplication and division by constant powers of 2 to shifts on its own, so write whichever is clearer.

Swapping two ints without a temporary

A classic XOR trick:

int a = 5, b = 3;
a ^= b;
b ^= a;
a ^= b;
System.out.println(a + " " + b);   // 3 5

Cute, but rarely worth using over a temporary variable — modern compilers handle the temporary case fine.

A demonstration

java— editable, runs on the server

When to use these vs. EnumSet

For a small fixed set of flags in modern Java, EnumSet<MyFlag> is usually clearer and just as efficient — it stores enum values as a single long bitmask under the hood, so you get the readability of Set<MyFlag> with bitwise-fast operations:

EnumSet<Permission> perms = EnumSet.of(Permission.READ, Permission.WRITE);
perms.add(Permission.EXECUTE);
perms.contains(Permission.READ);   // true

Reach for raw bit operations only when you're dealing with binary formats, hardware registers, or hot paths where int-packing matters.

What's next

Java Strings — the reference type you'll work with more than any other.

Practice

Practice

What does 1 << 4 evaluate to?