這里記錄下運(yùn)算符中重要的知識(shí)點(diǎn)。
二元運(yùn)算符
除0
進(jìn)行除法運(yùn)算時(shí)需要注意, 整數(shù)除以 0 會(huì)拋出異常,但是浮點(diǎn)數(shù)除以 0 會(huì)得到無窮大或者 NaN。
<pre mdtype="fences" cid="n7" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">System.out.println(0.0 / 0); // NaN
System.out.println(1.0 / 0); // Infinity
System.out.println(1 / 0); // Exception in thread "main" java.lang.ArithmeticException: / by zero</pre>
隱式類型轉(zhuǎn)換
<pre mdtype="fences" cid="n20" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">short s1 = 1;
s1 = s1 + 1; // error</pre>
Java 執(zhí)行二元操作時(shí)會(huì)先將操作數(shù)轉(zhuǎn)化為同一種類型,再進(jìn)行計(jì)算,轉(zhuǎn)化規(guī)則為兩個(gè)操作數(shù)中如果有一個(gè)是 double 或 float 或 long 時(shí), 另一個(gè)數(shù)就轉(zhuǎn)化為相應(yīng)的double 或 float 或 long,如果沒有,則都轉(zhuǎn)化為 int 類型再進(jìn)行計(jì)算,上述 s1 + 1 先將 s1 轉(zhuǎn)化為 int 類型(隱式轉(zhuǎn)換),然后執(zhí)行 + 運(yùn)算,操作得出的結(jié)果也是 int 類型, 不能賦值給 short 類型,因此會(huì)出錯(cuò)。
<pre mdtype="fences" cid="n24" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">s1 += 1;
s1++;</pre>
但是上述語(yǔ)句是有效的,因?yàn)槠涞韧?s1 = (short) (s1 + 1);
位運(yùn)算
<pre mdtype="fences" cid="n54" lang="java" class="md-fences md-end-block ty-contain-cm modeLoaded" spellcheck="false" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">~4 = -5;</pre>
上述代碼對(duì) 4 進(jìn)行~ 運(yùn)算,對(duì) 4 所有位進(jìn)行取反, 求值過程如下:
4 (0000 0000 0000 0000 0000 0000 0000 0100)按位取反:1111 1111 1111 1111 1111 1111 1111 1011(補(bǔ)碼)
求反碼(補(bǔ)碼 - 1):1111 1111 1111 1111 1111 1111 1111 1010(反碼)
求原碼(最高位不變,其他位取反):1000 0000 0000 0000 0000 0000 0000 0101(-5)
這道題的求值過程用到了原碼,反碼,補(bǔ)碼的知識(shí),簡(jiǎn)單總結(jié)一下:
帶符號(hào)整數(shù)有原碼、反碼、補(bǔ)碼等幾種編碼方式。原碼即直接將真值轉(zhuǎn)換為其相應(yīng)的二進(jìn)制形式,而反碼和補(bǔ)碼是對(duì)原碼進(jìn)行某種轉(zhuǎn)換編碼方式。
計(jì)算機(jī)運(yùn)算是都是通過補(bǔ)碼進(jìn)行運(yùn)算,原因是為了只使用加法運(yùn)算而不使用減法運(yùn)算
求位運(yùn)算結(jié)果需要將最終的補(bǔ)碼轉(zhuǎn)換為原碼,再通過原碼求其真值
整數(shù)的原碼,反碼,補(bǔ)碼都相同
復(fù)數(shù)的反碼,補(bǔ)碼需要根據(jù)原碼進(jìn)行轉(zhuǎn)換計(jì)算
運(yùn)算符優(yōu)先級(jí)
| 優(yōu)先級(jí) | 分類 | 運(yùn)算符 | 結(jié)合性 | ||
|---|---|---|---|---|---|
| 1 | method call | [] . ()(方法調(diào)用) | 從左到右 | ||
| 2 | postfix | exper++ exper-- | 從右到左 | ||
| 3 | unary | ++exper --exper +exper -exper ~ ! ()(強(qiáng)制類型轉(zhuǎn)換) new | 從右到左 | ||
| 4 | multiplicative | * / % | 從左到右 | ||
| 5 | additive | + - | 從左到右 | ||
| 6 | shift | << >> >>> | 從左到右 | ||
| 7 | relational | < > <= >= instanceof | 從左到右 | ||
| 8 | equality | == != | 從左到右 | ||
| 9 | bitwise AND | & | 從左到右 | ||
| 10 | bitwise exclusive OR | ^ | 從左到右 | ||
| 11 | bitwise inclusive OR | 從左到右 | |||
| 12 | logical AND | && | 從左到右 | ||
| 13 | logical OR | 從左到右 | |||
| 14 | ternary | ? : | 從右到左 | ||
| 15 | assignment | = += -= *= 、= %= &= | = ^= <<= >>= >>>= | 從右到左 |