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
| Operator | Name | What it does |
|---|---|---|
& | AND | bit is 1 only if both bits are 1 |
| | OR | bit is 1 if either bit is 1 |
^ | XOR | bit is 1 if the two bits differ |
~ | NOT (complement) | flips every bit |
<< | left shift | shifts bits left, fills with 0 on the right |
>> | signed right shift | shifts right, fills with the sign bit on left |
>>> | unsigned right shift | shifts 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); // 0Shifts
<< 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); // -1Practical 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 readThis 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 5Cute, but rarely worth using over a temporary variable — modern compilers handle the temporary case fine.
A demonstration
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); // trueReach 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
What does 1 << 4 evaluate to?