インタビューで、私のインタビュアーは私に尋ねました:
次のコードで&&を&に置き換えると何がうまくいかない可能性があります:
String a=null; if (a!=null && a.length()>10) {...}
&&
論理積演算子です(短絡動作を実行します。つまり、2番目のオペランドは必要な場合にのみ評価されます)
&
はビット単位のAND演算子です(ビット単位の&演算子はビット単位のAND演算を実行します)。
短絡動作がないため、が得られNullPointerException
ます。
を使用すると短絡が発生しないため、 ANullPointerException
がスローされます&
。つまり、左側のオペランドの結果が。であっても、右側のオペランドは常に評価されfalse
ます。を使用すると、左側のオペランドが。の場合にのみ&&
右側のオペランドが評価されます。true
セクション15.22.2。ブール論理演算子&、^、および| および15.23。条件付き-Java言語仕様の演算子&&は、この動作を説明しています。
とった :
ここでの単一のアンパサンドは、につながりNullPointerException
ます。&&は論理AND演算子であり、2番目のオペランドは必要な場合にのみ評価されます。
&&を使用すると、最初の式がfalseの場合、2番目の式は評価されません。 &一方、何があっても両方の式を評価します。
あなたの場合、'&&'を&に置き換えるとスローされますNullPointedException
&
と&&
式の評価の優先順位が異なり()
、隣接する式を囲まないと、場合によっては「驚き」が発生する可能性があります。特に、優先順位がかなり遅いため、論理式を組み合わせた結果を組み合わせない限り、&&
通常は必要ありません。()
しかし、&
あなたを警戒から外すにはちょうど十分早いです。
&&
は短絡しています。つまり、最初の式がfalseの場合、2番目の式はまったく評価されません。 &
短絡しません。上記の例では、これは&&
2番目の式でNullPointerExceptionがスローされないことを意味します。多くの場合、の重要な機能です&&
。
Java以外のCのような言語に関連する:上記の2つの落とし穴を乗り越えたら、操作が実際に何をするかという問題があります。評価される両方の式が「ブール」結果を生成する場合、値は0x00または0x01のいずれかに昇格し、&
and&&
演算子は本質的に同じ答えを生成します。&&
ただし、式の1つがブール値でない場合は、たとえば、演算子がtrueと評価された場合でも、0x01と0x02をAND演算して、0x00を生成する可能性があります。(Javaでは、の非ブールオペランドは許可されておらず、。&&
のブール/整数オペランドの混合も許可されていないため、特に問題にはなりません&
。)