How do I pass multiple values through a parameter using bitwise operations?
Author: Deron Eriksson
Description: This Java tutorial describes passing multiple values through a method parameter using bitwise operations.
Tutorial created using: Windows XP || JDK 1.5.0_09 || Eclipse Web Tools Platform 1.5.1


In this short tutorial, I'll describe how you can use bitwise operations to pass multiple values to a method using just one parameter rather than using an object or multiple parameters. This technique is more of a C technique than a JavaSW technique, so you probably won't see it used in Java very much since it's not very object-oriented, but it can be used to avoid the creation of long lists of method parameters, or the creation of excessive classes in your application. So, if used wisely it can potentially simplify code maintenance, but the bitwise nature of the technique versus object-oriented solutions would cause most Java developers to avoid it.

As you know, all math in computers basically boils down to 1's and 0's. Boolean algebra describes ANDing and ORing these 1's and 0's together. You can think of 1 as true and 0 as false. I don't really want to write too much more about Boolean algebra, but it's good to know the following:

0 AND 0 = 0       0 OR 0 = 0       0 XOR 0 = 0
1 AND 0 = 0       1 OR 0 = 1       1 XOR 0 = 1
0 AND 1 = 0       0 OR 1 = 1       0 XOR 1 = 1
1 AND 1 = 1       1 OR 1 = 1       1 XOR 1 = 0

In Java, AND is represented by the & operator, OR is represented by the | operator, and XOR (exclusive-OR) is represented by the ^ operator.

The int data type in Java can be thought of as a list of 32 1's and 0's, with the far-right digit representing 2 raised to the power of 0, the next digit representing 2 raised to the power of 1, and so on. To convert this list of 1's and 0's to base 10 numbering, you can sum up all of the powers of 2. As an example, 27 is represented in the following:

00000000 00000000 00000000 00011011  → 24 + 23 + 0 + 21 + 20 = 16 + 8 + 0 + 2 + 1 = 27

If you think of each binary digit (1 or 0) as a true or false switch, this means that there are actually 32 potential true/false switches in a Java 'int', which takes up 32 'bits' of memory. 8 bits are known collectively as a byte.

To see an interesting use of these little 1/0 switches, I created the BitwiseTest class, shown below. I have 4 int constants, named HAMBURGER, CHEESEBURGER, FRIES, and SODA. Notice that each constant is a different power of 2. In the main method of this class, the orderFood() method is called twice, once for Bob and once for Jane. Notice the second parameter in the call to orderFood(). In the first orderFood call, we see 'HAMBURGER | FRIES', which is HAMBURGER bitwise-OR'd to FRIES. As a result, we see that the second parameter in the first orderFood call works out to this:

 HAMBURGER = 00000000 00000000 00000000 00000001
 FRIES     = 00000000 00000000 00000000 00000100 OR
 -----------------------------------------------
             00000000 00000000 00000000 00000101

This has the effect of passing both the HAMBURGER and the FRIES values into orderFood, since they are bitwise-OR'd together.

BitwiseTest.java

package test;

public class BitwiseTest {
	static final int HAMBURGER = 1;    // 00000001
	static final int CHEESEBURGER = 2; // 00000010
	static final int FRIES = 4;        // 00000100
	static final int SODA = 8;         // 00001000
	
	public static void main(String[] args) {
		orderFood("Bob", HAMBURGER | FRIES);
		orderFood("Jane", FRIES | SODA | CHEESEBURGER);
	}

	public static void orderFood(String person, int foods) {
		System.out.println(person + " ordered:");
		if ((HAMBURGER & foods) == HAMBURGER)
			System.out.println("\tHamburger");
		if ((CHEESEBURGER & foods) == CHEESEBURGER)
			System.out.println("\tCheeseburger");
		if ((FRIES & foods) == FRIES)
			System.out.println("\tFries");
		if ((SODA & foods) == SODA)
			System.out.println("\tSoda");
	}
}

Now, let's discuss the orderFood method. The name of the person ordering food is passed in as the first parameter, and the name is output to the console. After that, we have some interesting if statements. First, HAMBURGER is bitwise-AND'd to the 'foods' variable, and if this equals HAMBURGER, it outputs 'Hamburger' to the console with a tab in front of it. What exactly is going on here? Let's look at the following bitwise-AND's:

 HAMBURGER    = 00000000 00000000 00000000 00000001
 foods        = 00000000 00000000 00000000 00000101 AND
 --------------------------------------------------
                00000000 00000000 00000000 00000001
             
 CHEESEBURGER = 00000000 00000000 00000000 00000010
 foods        = 00000000 00000000 00000000 00000101 AND
 --------------------------------------------------
                00000000 00000000 00000000 00000000
                
 FRIES        = 00000000 00000000 00000000 00000100
 foods        = 00000000 00000000 00000000 00000101 AND
 --------------------------------------------------
                00000000 00000000 00000000 00000100
                
 SODA         = 00000000 00000000 00000000 00001000
 foods        = 00000000 00000000 00000000 00000101 AND
 --------------------------------------------------
                00000000 00000000 00000000 00000000

Notice that 'foods' contains 1's at the first and third digits from the right. When 'foods' gets AND'd to HAMBURGER, we see that the result has a 1 in the first digit. CHEESEBURGER AND'd to 'foods' gives 0 in all digits. FRIES AND'd to 'foods' gives 1 in the third digit. SODA AND'd to 'foods' gives 0 in all digits.

In each of our 'if' statements in the orderFood method, we compare each of the results above and see if it equals the particular int constant. If the result is true, it outputs the particular food. Since ((HAMBURGER & foods) == HAMBURGER) is true and ((FRIES & foods) == FRIES) is true, these particular foods are output to the console.

If we execute BitwiseTest, we see the following result:

Bob ordered:
	Hamburger
	Fries
Jane ordered:
	Cheeseburger
	Fries
	Soda

This tutorial has shown an interesting use of bitwise operators in Java. It's not a typical Java-style solution, so I don't really recommend it except in very rare cases.