Bitwise and Shift Operators in Java
Bitwise operators work on the binary representation of integers. They let you pack multiple booleans into a single int, check individual bits, and multiply or divide by powers of two without multiplication.
The operators
| Op | Name | Example | Result |
|---|---|---|---|
& | AND | 0b1100 & 0b1010 | 0b1000 |
| | OR | 0b1100 | 0b1010 | 0b1110 |
^ | XOR | 0b1100 ^ 0b1010 | 0b0110 |
~ | NOT | ~0b1100 | inverts every bit |
<< | Shift left | 5 << 2 | 20 β multiply by 2Β² |
>> | Arithmetic shift right | -8 >> 1 | -4 β sign-preserving |
>>> | Logical shift right | -8 >>> 1 | 2147483644 β zero fill |
Flags as bitmasks
static final int READ = 1 << 0; // 0001
static final int WRITE = 1 << 1; // 0010
static final int EXECUTE = 1 << 2; // 0100
int perms = READ | WRITE;
boolean canRead = (perms & READ) != 0; // set?
perms |= EXECUTE; // add flag
perms &= ~WRITE; // clear flag
perms ^= READ; // toggle
For type-safe flags, prefer EnumSet β it's backed by bitmasks internally but keeps the code readable.
Sign-preserving vs zero-fill shift
int n = -8; // 11111111_11111111_11111111_11111000
n >> 1; // -4 β sign bit copied
n >>> 1; // 2147483644 β leading zero
Use >>> when you want to treat the value as unsigned (e.g. reading hashes, bit manipulation).
Fast math
x << n; // x * 2βΏ
x >> n; // x / 2βΏ (rounding toward negative infinity)
x & (m - 1); // x mod m β when m is a power of 2
These micro-optimisations rarely matter β modern JITs do them for you. Readability usually wins.
Precedence trap
if (x & MASK == 0) { ... } // β parses as x & (MASK == 0)
if ((x & MASK) == 0) { ... } // β
always parenthesise
Common mistakes
- Mixing
&and&&β&is bitwise;&&is short-circuit logical. - Shifting by β₯ 32 on an
intβ the shift count is taken modulo 32.1 << 32 == 1, not 0. - Forgetting parentheses β
&has lower precedence than==.
Related
Pillar: Java operators. See also int, enum (for EnumSet).