Javaの&と&&の違いは何ですか?


168

いつも思っていた &&はJavaの演算子は両方のブールオペランドがtrueであるかどうかを確認するために&使用され、2つの整数型に対してビット単位の演算を実行するために使用される。

最近、&演算子を使用して両方のブールオペランドがtrueであるかどうかを確認することもできることを知りました。唯一の違いは、LHSオペランドがfalseの場合でも、RHSオペランドをチェックすることです。

&Java の演算子は内部的にオーバーロードされていますか?それとも、これの背後にある他の概念はありますか?



可能であれば、Doubleはショートカットを実行します。
ニコラスハミルトン

回答:


278

&<-は両方のオペランドを検証します
&& <-は最初のオペランドがfalseと評価された場合、結果がfalseになるため評価を停止します

(x != 0) & (1/x > 1)<-これは、評価して(x != 0)から評価(1/x > 1)して&を実行することを意味します。問題は、x = 0の場合、例外がスローされることです。

(x != 0) && (1/x > 1)<-これは評価(x != 0)を意味し、これがtrueの場合にのみ評価する(1/x > 1)ので、x = 0の場合、これは完全に安全であり、(x!= 0)がfalseと評価されても、すべてが直接falseと評価されても例外はスローされません。評価せずに(1/x > 1)

編集:

exprA | exprB<-これは、評価してexprAから評価してexprBから実行することを意味し|ます。

exprA || exprB<-これは、評価することを意味します。exprAこれがfalse評価されexprB、を実行する場合のみです||


7
&を書く理由は何ですか&または| ifステートメントで?&&および||よりも速くなることはありません。すでに答えが得られているのに、なぜ2番目の条件をチェックしたいのですか?あなたは現実的な例を提供できますか?
Michu93 2017

14
@ Michu93:1つの例は、2番目の条件が常に必要な副作用を持つ関数呼び出しである場合です。副作用は通常避けなければならないので、それを必要とするのはまれなケースだけであり、私は現時点では現実的な例を考えることができません。
ハインジ

54

両方のオペランドを評価することによって遅延エバリュエーターではないことに加えて、ビット演算子の主な特性は、次の例のように、オペランドの各バイトを比較すると思います。

int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100

2
問題は、ビットごとの演算ではなく、論理ブール演算についてです。
ローンの侯爵

21
@EJPこれは、タイトルだけを読んでいる私のようなグーグルを助けます。
Ad Infinitum 2017年

29
boolean a, b;

Operation     Meaning                       Note
---------     -------                       ----
   a && b     logical AND                    short-circuiting
   a || b     logical OR                     short-circuiting
   a &  b     boolean logical AND            not short-circuiting
   a |  b     boolean logical OR             not short-circuiting
   a ^  b     boolean logical exclusive OR
  !a          logical NOT

short-circuiting        (x != 0) && (1/x > 1)   SAFE
not short-circuiting    (x != 0) &  (1/x > 1)   NOT SAFE

多分この他の質問があまりにも役立ちます、編集のためにあなたのアンドレアスありがとう:stackoverflow.com/questions/4014535/vs-and-vs
トレス

11

引数の種類によって異なります...

整数の引数の場合、単一のアンパサンド( "&")は「ビット単位のAND」演算子です。2つのアンパサンド( "&&")は、2つのブール引数以外には定義されていません。

ブール引数の場合、単一のアンパサンドは(無条件の)「論理AND」演算子を構成しますが、二重のアンパサンド(「&&」)は「条件付き論理AND」演算子です。つまり、単一のアンパサンドは常に両方の引数を評価しますが、二重のアンパサンドは最初の引数がtrueの場合にのみ2番目の引数を評価します。

他のすべての引数のタイプと組み合わせでは、コンパイル時エラーが発生するはずです。


9

&&は短絡演算子ですが、&はAND演算子です。

これを試して。

    String s = null;
    boolean b = false & s.isEmpty(); // NullPointerException
    boolean sb = false && s.isEmpty(); // sb is false

7

JLS(15.22.2)で指定されているとおりです。

&、^、または|の両方のオペランド 演算子はブール型またはブール型であり、ビットごとの演算子式の型はブール型です。すべての場合において、必要に応じて、オペランドはボックス化解除変換(§5.1.8)の対象になります。

&の場合、両方のオペランド値がtrueの場合、結果値はtrueです。それ以外の場合、結果はfalseです。

^の場合、オペランドの値が異なる場合、結果の値はtrueです。それ以外の場合、結果はfalseです。

|の場合、両方のオペランド値がfalseの場合、結果値はfalseです。それ以外の場合、結果はtrueです。

「トリック」は&整数のビット演算子ブール論理演算子です。では、なぜこれを演算子のオーバーロードの例として見るのが妥当でしょうか。


7

私の答えはより理解しやすいと思います:

とには2つの違いが &あり&&ます。

論理ANDとして使用する場合

&そして、&&論理的なことができANDたとき、&または&&左と右の式の結果がすべて真で、全体の演算結果が真であることができます。

いつ&&&論理的にAND、違いがあります:

&&論理として使用する場合AND場合、左の式の結果がfalseの場合、右の式は実行されません。

例を見てみましょう:

String str = null;

if(str!=null && !str.equals("")){  // the right expression will not execute

}

使用する場合&

String str = null;

if(str!=null & !str.equals("")){  // the right expression will execute, and throw the NullPointerException 

}

その他の例:

int x = 0;
int y = 2;
if(x==0 & ++y>2){
    System.out.print(“y=”+y);  // print is: y=3
}

int x = 0;
int y = 2;
if(x==0 && ++y>2){
    System.out.print(“y=”+y);  // print is: y=2
}

&はビット演算子として使用できます

&ビットごとのAND演算子 として使用できますが、使用&&できません。

ビットごとのAND "&"演算子は、オペランドの両方のビットが1の場合にのみ1を生成します。ただし、両方のビットが0であるか、両方のビットが異なる場合、この演算子は0を生成します。より正確にビットごとにAND "&"演算子は、2つのビットのいずれかが1の場合は1を返し、いずれかのビットが0の場合は0を返します。 

wikiページから:

http://www.roseindia.net/java/master-java/java-bitwise-and.shtml


4

'&&':-論理AND演算子で、引数の論理関係に基づいてブール値trueまたはfalseを生成します。

例:-Condition1 && Condition2

Condition1がfalseの場合、(Condition1 && Condition2)は常にfalseになります。これが、この論理演算子が別の条件を評価しないため、短絡演算子とも呼ばれる理由です。Condition1がfalseの場合、Condtiton2を評価する必要はありません。

Condition1がtrueの場合、Condition2が評価され、trueの場合、結果全体がtrueになり、それ以外の場合はfalseになります。

'&':-ビットごとのAND演算子です。両方の入力ビットが1の場合、出力に1が生成されます。それ以外の場合はゼロ(0)を生成します。

例えば:-

int a = 12; // 12のバイナリ表現は1100です

int b = 6; // 6のバイナリ表現は0110です

int c =(a&b); //(12&6)のバイナリ表現は0100です

cの値は4です。

参考までに、こちらを参照してくださいhttp://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html


3

&&そして、||短絡演算子と呼ばれています。これらが使用される||場合、for-最初のオペランドがに評価されるtrue場合、残りのオペランドは評価されません。の場合&&-最初のオペランドがに評価されたfalse場合、残りのオペランドはまったく評価されません。

したがってif (a || (++x > 0))、この例では、変数xは、aがあっtrueた場合に増分されません。


3

ブール値では、2つの間に出力の違いはありません。&&と&または||を入れ替えることができます と| そしてそれはあなたの表現の結果を決して変えることはありません。

違いは、情報が処理される舞台裏にあります。a = 0およびb = 1の式「(a!= 0)&(b!= 0)」を右にすると、次のようになります。

left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false

(a != 0) && ( b != 0)a = 0およびb = 1のときに式を記述すると、次のことが起こります。

a != 0 -->false
expression returns false

特にブール式や複雑な引数を多数実行する場合は、ステップが少なく、処理が少なく、コーディングが優れています。


2
オペランドに副作用がある場合、式の結果全体を変更します。
ローンの侯爵

3

&&と||以外にも 短絡であるため、2つの形式を混合する場合は演算子の優先順位も考慮してください。結果1と結果2に異なる値が含まれていることは、誰にもすぐにわかるとは思いません。

boolean a = true;
boolean b = false;
boolean c = false;

boolean result1 = a || b && c; //is true;  evaluated as a || (b && c)
boolean result2 = a  | b && c; //is false; evaluated as (a | b) && c

0

&は両方の条件を評価する必要がある場合があるため、両方の条件をチェックするために使用されるビット単位の演算子プラスです。ただし、&&論理演算子は、最初の条件が真になると、2番目の条件に進みます。


0

すべての答えはgreatであり、noより多くの答えis needed があるようですが、私は&&呼び出された演算子について何かを指摘したくありませんでしたdependent condition

演算子&&を使用する式では、条件(これをと呼びます)dependent conditionは、依存する条件の評価を意味のあるものにするために、別の条件が真であることが必要になる場合があります。

この場合、エラーを防ぐために、依存条件を&&演算子の後に配置する必要があります。

式について考えてみましょう(i != 0) && (10 / i == 2)。従属条件(10 / i == 2)appear after&&ゼロによる除算の可能性を防ぐためにオペレーターに必要です。

もう一つの例 (myObject != null) && (myObject.getValue() == somevaluse)

そして別のもの:&&||呼ばれている短絡評価第二引数が実行または評価されるため、引数がないにのonly iffirstnot sufficedeterminevalueexpression

参考資料:Java™How To Program(Early Objects)、第10版

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.