Java Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

> CHECK OUT THE COURSE

Authors Top

If you have a few years of experience in the Java ecosystem, and you’d like to share that with the community, have a look at our Contribution Guidelines.

1. Overview

Java provides a set of bitwise operators. Those operators allow us to conveniently manipulate individual bits of a number.

However, when we compare the result of a bitwise operation, we might fall into a common pitfall.

In this quick tutorial, we'll discuss why we may encounter the Java compile-time error “bad operand types for binary operator”, and how to resolve the problem.

2. Introduction to the Problem

As usual, we'll understand the problem through an example. But, first, let's take a look at a simple method:

public void checkNumber() {
    List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
    intList.forEach(i -> {
        if (i & 1 == 1) {
            System.out.println(i + " is odd.");
        } else {
            System.out.println(i + " is even.");
        }
    });
}

As we can see, the checkNumber method walks through intList, and checks and outputs if each number is even or odd.

We should note that the odd-checking logic in the method is not implemented in a common way: i % 2 == 1. Instead, we perform the bitwise AND (&) operation on an Integer number (i) and 1. If the result is 1, we know the integer i is an odd number: i & 1 ==1.

However, when we try to test the method above, the code surprisingly doesn't compile:

java: bad operand types for binary operator '&'
  first type:  java.lang.Integer
  second type: boolean

Next, let's understand what the cause of the problem is and how to solve it.

3. Understanding Java Operator Precedence

First of all, the error message is pretty straightforward. It says we attempt to do a bitwise AND on a boolean type and an Integer type.

However, it's weird as we literally wrote “i & 1” in the code. Why does the compiler think a boolean type participates in the bitwise AND operation?

This is because the “==” operator has higher precedence than the “&” operator. That is to say the expression “i & 1 == 1” is the same as “i & (1 == 1)“. Thus, we have “i & true (boolean)“.

Now, we may ask: “Ok, == has higher precedence than &. But why does ‘i % 2 == 1‘ work as expected?”

To answer that question, we need to take a closer look at Java operators' precedence rule.

Java has provided quite a number of operators. In practice, we often use different operators together. Therefore, understanding the precedence of Java operators is essential. Otherwise, we may have an unexpected result.

Next, let's have a look at the Java operator precedence rule (the higher in the table an operator appears, the higher precedence it has):

Operators Precedence
postfix expr++ expr
unary ++exprexpr +exprexpr ~ !
multiplicative * / %
additive + –
shift << >> >>>
relational < > <= >= instanceof
equality == !=
bitwise AND &
bitwise exclusive OR ^
bitwise inclusive OR |
logical AND &&
logical OR ||
ternary ? :
assignment = += -= *= /= %= &= ^= |= <<= >>= >>>=

As we can see in the list above, the modulo operator (%) has higher precedence than the equality operator (==). On the other hand, the bitwise AND operator (&) is below the equality operator (==) in the table.

That's why “i % 2 == 1” works as expected but “i & 1 == 1” does not.

We've encountered a compile-time error in our example. So, we can detect the problem relatively early. However, imagine some implementation with the operator precedence bug compiles but produces a wrong result. Finding the real cause of the problem could unnecessarily take us much time.

So, it's worth keeping the Java operator precedence rule in mind.

4. Fixing the Problem

Now that we understand the cause of the problem, fixing the problem isn't a hard job. We just need to add parentheses to the bitwise AND operation:

if (i & 1 == 1)  -->  if ((i & 1) == 1)

After the fix, if we run the method once again, we'll see the compiler doesn't complain anymore, and we receive the expected output:

1 is odd.
2 is even.
3 is odd.
4 is even.
5 is odd.
6 is even.
7 is odd.

5. Conclusion

In this quick article, we've analyzed the compilation error “bad operand types for binary operator” through a bitwise AND operation example.

Further, we've discussed Java operators' precedence rule.

Finally, we've fixed the problem.

Java bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
Comments are closed on this article!