Encodera

Thanks for reading!

Donate to the site — we work hard for you.

How to use bit flags

Short answer

Give each flag its own bit (1, 2, 4, 8...), combine flags with | and check them with &:

static final int READ = 1;
static final int WRITE = 1 << 1;
static final int DELETE = 1 << 2;
 
void main() {
    int perms = READ | WRITE;
 
    IO.println((perms & WRITE) != 0);
    IO.println((perms & DELETE) != 0);
}

Output:

true
false

Set, clear, toggle

|= turns a bit on, &= ~ turns it off, ^= toggles it:

static final int READ = 1;
static final int WRITE = 1 << 1;
static final int DELETE = 1 << 2;
 
void main() {
    int perms = READ;
    perms |= DELETE;
    IO.println(Integer.toBinaryString(perms));
 
    perms &= ~READ;
    IO.println(Integer.toBinaryString(perms));
 
    perms ^= WRITE;
    IO.println(Integer.toBinaryString(perms));
}

Output:

101
100
110

All flags at once

Check that all required flags are on, and count the ones that are on:

static final int READ = 1;
static final int WRITE = 1 << 1;
static final int DELETE = 1 << 2;
 
void main() {
    int perms = READ | WRITE;
    int required = READ | WRITE;
 
    IO.println((perms & required) == required);
    IO.println(Integer.bitCount(perms));
}

Output:

true
2

EnumSet instead of flags

In new code flags are easier to keep in an EnumSet: inside it works the same way, but the code reads better and the output is clearer:

enum Permission { READ, WRITE, DELETE }
 
void main() {
    EnumSet<Permission> perms = EnumSet.of(Permission.READ, Permission.WRITE);
    perms.remove(Permission.READ);
    perms.add(Permission.DELETE);
 
    IO.println(perms);
    IO.println(perms.contains(Permission.WRITE));
}

Output:

[WRITE, DELETE]
true

Common mistake

Forgetting the parentheses. & has lower precedence than !=, so the expression without parentheses does not compile:

static final int WRITE = 2;
 
void main() {
    int perms = 3;
    if (perms & WRITE != 0) {
        IO.println("can write");
    }
}

Output:

Main.java:5: error: bad operand types for binary operator '&'

The correct form is (perms & WRITE) != 0. Another mistake is numbering flags 1, 2, 3: 3 has two bits set and equals 1 | 2.

Functions used in this recipe

  • & | ^ ~ << >> >>> — Bitwise operators work with individual bits of integers: AND, OR, XOR, NOT and shifts.
  • EnumSet — A set of values of one enum. Works like a set of bit flags, but with readable code.
  • Integer.toBinaryString() — Writes a number in binary. Related methods are toHexString() and toOctalString().
  • += -= *= /= — Performs an operation and stores the result back in the same variable.

Thanks for reading!

Donate to the site — we work hard for you.