如何解決Java錯誤“二元運算符的操作數類型錯誤”
- java
一、概述
Java 提供了一組位運算符。這些運算符使我們能夠方便地操作數字的各個位。
但是,當我們比較按位運算的結果時,我們可能會陷入一個常見的陷阱。
在這個快速教程中,我們將討論為什麼我們可能會遇到 Java 編譯時錯誤“二元運算符的操作數類型錯誤”,以及如何解決該問題。
2. 問題介紹
像往常一樣,我們將通過一個例子來理解這個問題。但是,首先,讓我們看一個簡單的方法:
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.");
}
});
}
如我們所見, checkNumber
方法遍歷intList
,檢查並輸出每個數字是偶數還是奇數。
我們應該注意,該方法中的奇數檢查邏輯不是以常見的方式實現的: i % 2 == 1
。相反,我們對Integer
( i
) 和 1 執行按位與 (&) 運算。如果結果為 1,我們知道整數i
是奇數: i & 1 ==1
。
但是,當我們嘗試測試上面的方法時,令人驚訝的是,代碼沒有編譯:
java: bad operand types for binary operator '&'
first type: java.lang.Integer
second type: boolean
接下來,讓我們了解一下問題的原因是什麼以及如何解決它。
3. 理解 Java 運算符優先級
首先,錯誤消息非常簡單。它說我們嘗試對boolean
類型和Integer
類型進行按位與。
然而,這很奇怪,因為我們在代碼中直接寫了“ i & 1
”。為什麼編譯器認為boolean
類型參與了按位與運算?
這是因為“ ==
”運算符的優先級高於“ &
”運算符。也就是說,表達式“ i & 1 == 1
”與“ i & (1 == 1)
”是一樣的。因此,我們有“ i & true (boolean)
”。
現在,我們可能會問:“好吧, == 的優先級高於&
。但為什麼 ' i % 2 == 1
' 會按預期工作呢?”
要回答這個問題,我們需要仔細研究 Java 運算符的優先規則。
Java提供了相當多的運算符。在實踐中,我們經常將不同的運算符一起使用。因此,了解 Java 運算符的優先級至關重要。否則,我們可能會得到意想不到的結果。
接下來,讓我們看一下Java運算符優先級規則(運算符在表中出現的位置越高,其優先級越高):
運營商 | 優先級 |
---|---|
後綴 | `expr` ++ `expr` — |
一元 | ++ `expr` — `expr` + `expr` – `expr` ~ ! |
乘法的 | * / % |
添加劑 | + – |
轉移 | << >> >>> |
關係 | < > <= >= instanceof |
平等 | == != |
按位與 | & |
按位異或 | ^ |
按位包含 OR | ` |
邏輯與 | && |
邏輯或 | ` |
三元 | ? : |
任務 | `= += -= *= /= %= &= ^= |
正如我們在上面的列表中看到的,模運算符 (%) 比相等運算符 ( ==
) 具有更高的優先級。另一方面,按位與運算符 (&) 在表中的等式運算符 (==) 下方。
這就是為什麼“ i % 2 == 1
”按預期工作而“ i & 1 == 1
”沒有按預期工作的原因。
我們在示例中遇到了編譯時錯誤。因此,我們可以相對較早地發現問題。但是,想像一下某些具有運算符優先級錯誤的實現編譯但會產生錯誤的結果。找到問題的真正原因可能會不必要地花費我們很多時間。
因此,值得牢記 Java 運算符優先規則。
4. 解決問題
既然我們了解了問題的原因,解決問題就不是一件難事。我們只需要在按位與運算中添加括號:
if (i & 1 == 1) --> if ((i & 1) == 1)
修復後,如果我們再次運行該方法,我們將看到編譯器不再抱怨,並且我們收到了預期的輸出:
1 is odd.
2 is even.
3 is odd.
4 is even.
5 is odd.
6 is even.
7 is odd.
5. 結論
在這篇快速文章中,我們通過按位與運算示例分析了編譯錯誤“二元運算符的錯誤操作數類型”。
此外,我們還討論了 Java 運算符的優先規則。
最後,我們解決了這個問題。