Java Error “bad operand types for binary operator” – Java Error “bad operand types for binary operator”

最后修改: 2022年 4月 6日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

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

Java提供了一组bitwise运算符。这些运算符使我们能够方便地操作一个数字的各个比特。

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.

在这个快速教程中,我们将讨论为什么我们可能会遇到Java编译时的错误 “二进制操作符的操作数类型不好”,以及如何解决这个问题。

2. Introduction to the Problem

2.对问题的介绍

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.

我们可以看到,checkNumber方法遍历intList,检查并输出每个数字是偶数还是奇数。

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.

我们应该注意到,该方法中的奇数检查逻辑并没有以一种常见的方式实现。i % 2 == 1。相反,我们对一个整数i)和1进行位数和(&)操作。如果结果是1,我们知道整数i是一个奇数。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

3.了解Java操作符的优先级

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.

首先,错误信息是非常直接的。它说我们试图对boolean类型和Integer类型做一个位数和。

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?

然而,这很奇怪,因为我们在代码中真的写了”i & 1“。为什么编译器认为boolean类型参与了bitwise AND操作?

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)“.

这是因为==“运算符的优先级高于”&“运算符。也就是说,表达式”i & 1 == 1“与”i & (1 == 1)“相同。因此,我们有”i & true (boolean)“。

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

现在,我们可能会问:”好吧,==的优先级比&高。但为什么’i % 2 == 1‘能如期工作呢?”

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

要回答这个问题,我们需要仔细研究一下Java操作符的优先级规则。

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.

Java提供了相当多的operators。在实践中,我们经常一起使用不同的操作符。因此,了解Java操作符的优先级是至关重要的。否则,我们可能会出现意想不到的结果。

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):

接下来,让我们看看Java操作符的优先级规则(操作符在表中出现的位置越高,它的优先级就越高)。

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.

从上面的列表中我们可以看到,模数运算符(%)的优先级高于平等运算符(==。另一方面,位数和运算符(&)在表中低于平等运算符(==)/strong>。

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

这就是为什么”i % 2 == 1“能按预期工作,而”i & 1 == 1“却不能。

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.

所以,值得注意的是,要记住Java操作符的优先规则。

4. Fixing the Problem

4.修复问题

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

5.总结

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.

此外,我们已经讨论了Java操作符的优先级规则。

Finally, we’ve fixed the problem.

最后,我们已经解决了这个问题。