5

Since I started programming Java, I've noticed that everyone was using && and || instead of & and |. What is the reason for this? I've been using && and || all this time because I didn't know you can use & and | on booleans.

class A{static{
  boolean t = true;
  boolean f = false;
  System.out.println("&ff " + (f&&f) + " " + (f&f));
  System.out.println("&ft " + (f&&t) + " " + (f&t));
  System.out.println("&tf " + (t&&f) + " " + (t&f));
  System.out.println("&tt " + (t&&t) + " " + (t&t));
  System.out.println("|ff " + (f||f) + " " + (f|f));
  System.out.println("|ft " + (f||t) + " " + (f|t));
  System.out.println("|tf " + (t||f) + " " + (t|f));
  System.out.println("|tt " + (t||t) + " " + (t|t));
}}

As far as I can tell, they are the same:

$ javac A.java && java A
&ff false false
&ft false false
&tf false false
&tt true true
|ff false false
|ft true true
|tf true true
|tt true true
Exception in thread "main" java.lang.NoSuchMethodError: main

Does using || and && improve my code in any way?


As a simple test, I replaced hundreds of occurrences with the short form, and all of my unit tests still pass.

Dog
  • 7,707
  • 8
  • 40
  • 74

9 Answers9

16

|| and && uses short circuit evaluation

From same article

Short-circuit evaluation, minimal evaluation, or McCarthy evaluation denotes the semantics of some Boolean operators in some programming languages in which the second argument is only executed or evaluated if the first argument does not suffice to determine the value of the expression

Consider you have an object and you want to check one of its property for some value if you do:

if(obj != null & obj.ID == 1)

If your object obj is null you will get a null reference exception, since you used single &, the first condition evaluate to false, but it will still continue to the next condition and raising null reference exception.

If you used && then the second condition will never get evaluated, thus no exception.

if(obj != null && obj.ID == 1)

With your code you will not see any difference, but using bitwise | or & with multiple conditions would result in no short circuiting at all.

More Explanation.


consider that you following code:

Boolean conditionA = 2 > 1; //some condition which returns true
if(conditionA | obj.SomeTimeConsumingMethod()){

}

Now in above code snippet, suppose you have an object with a method SomeTimeConsumingMethod which takes a lot of time in processing and returns true or false. If you use single | it would evaluate both the conditions, since first conditionA is true it will process obj.SomeTimeConsumingMethod as well. End result will be true for the whole if statement since | (OR) is used.

If your condition is using double || (OR Logical operator)

if(conditionA || obj.SomeTimeConsumingMethod())

Then the second condition obj.SomeTimeConsumingMethod() will not be evaluated. This is short circuiting and that just saved you from executing some time consuming method. Still the end result is true regardless of what was returned from obj.SomeTimeConsumingMethod().

Habib
  • 219,104
  • 29
  • 407
  • 436
  • 2
    +1 But it would be great if you can add few lines or explain it! – Rahul Tripathi Nov 22 '13 at 19:13
  • Does `|` and `&` not do it? How is this a reason? – Dog Nov 22 '13 at 19:16
  • @RahulTripathi, just added some details – Habib Nov 22 '13 at 19:18
  • @Dog, no single `|` and `&` doesn't produce short-circuiting and could result in exception/ undesired behaviour – Habib Nov 22 '13 at 19:19
  • 1
    @Habib:- Thats more like a Habib's answer! ;) But cant upvote more than once :( – Rahul Tripathi Nov 22 '13 at 19:19
  • @Habib: How can `|` result in an exception? I used it on all possible values in my code and it never did. *EDIT* Oh I see you're talking about when you use it like you did in your code. – Dog Nov 22 '13 at 19:20
  • @Dog, not with your code, I am saying it can result in undesired behaviour, check the example in my answer, if the `obj` is `null` you would get an exception if you combine multiple conditions with a single `&` – Habib Nov 22 '13 at 19:22
  • @Habib: I've just replaced hundreds of occurrences in one of my projects, and all the unit tests still pass. I don't see any "undesired behavior". – Dog Nov 22 '13 at 19:24
  • @Dog, I am not sure how you coded your test/code, but just consider the example. Suppose you have an object in your code, and you want to check if its not null then get value of ID, what would be your condition ? – Habib Nov 22 '13 at 19:27
  • Thank you for coming back and explaining it. The first line blurb was like "I don't want to think I'm dumb, but I don't understand the connection." Traditionally, didn't even realize single | and single & worked in Java. – Compass Nov 22 '13 at 19:29
  • @Habib, I don't use `null` in my code... I thought this was [common knowledge](http://lambda-the-ultimate.org/node/3186)? If I want to check something before executing a piece of code I do it like this: `if (something) dostuff()`. For your specific example I would have written it like this: `if (obj != null) dostuffwithobj` – Dog Nov 22 '13 at 19:30
  • @Dog, I think I am not explaining it well, See [truth table](http://www.cs.utah.edu/~germain/PPS/Topics/truth_tables_and_logic.html), based on that we know that if boolean AND `&&` is used and any of the operand is false, the whole condition would result in false. So if you have condition `if(obj != null && obj.ID == 1)`, if the `obj` is `null` second condition never gets evaluated. Now second condition could be access to a field or a complex method call which would return a boolean value. **if** you use single `&`, both of the condition will get evaulated regardless of the result of first.. – Habib Nov 22 '13 at 19:37
  • ...first condition. If you have the same if statement but with single `&`, and your `obj` is null, Both of your conditions will evaluate, thus resulting in NRE. – Habib Nov 22 '13 at 19:39
  • `if(obj != null && obj.ID == 1)` I personally find this code terrible and counterintuitive. I would not use it myself. @Dog I would argue your argument is invalid: With an `Optional` type instead of `null`, you may still want to do the same thing: `if (!obj.isNone() && obj.get() == 1)`. Then again, with pattern matching and higher order functions, you'd never write something like this. – Harold R. Eason Nov 22 '13 at 19:40
  • 1
    @HaroldR.Eason It is the norm in LISP, not just descendants of C. It is neither terrible nor counterintuitive---unless you have wrong intuition. – Marko Topolnik Nov 22 '13 at 19:49
  • @Habib: "second condition could be access to a complex method call" Are you saying it's for performance reasons now? I don't do premature optimization. It seems like you're main point is that `&&` can be used as a clever trick to do something with a value that might be `null`. – Dog Nov 22 '13 at 19:49
  • @MarkoTopolnik: Intuitive is subjective. A normal person may see `if(obj != null && obj.ID == 1)` => "if obj is not null and obj.id is 1", not knowing that it only works because the evaluator goes from left to right. Also it seems that you think it's the norm everywhere just because it's in LISP. In Haskell the question of whether to do this doesn't even arise. – Harold R. Eason Nov 22 '13 at 20:04
  • 1
    So if I get this right, you're saying that you should use `&&` everywhere because sometimes people use it to do the `null` trick you describe? What do you think about using `&` everywhere except when you explicitly want to short circuit? I do have cases in my websites where it needs to be strict to prevent side channel attacks (pointed out by @HaroldR.Eason's comment). – Dog Nov 22 '13 at 20:07
  • @HaroldR.Eason You are using the same point about intuition is me. One develops intuition by using a language---and when doing C/Java, the intuition tells you that the right argument is evaluated conditionally. I don't know where you got that I "seem to think that it's the norm everywhere". – Marko Topolnik Nov 22 '13 at 20:09
  • @HaroldR.Eason Your argument about this not being needed in a language with HOFs is also flawed: this idiom is in fact very useful in the *implementation* of higher-order functions. – Marko Topolnik Nov 22 '13 at 20:10
  • @MarkoTopolnik: No. You cant do this in Haskell because you cant use a value of the IO monad as an operand to `&&` or `||`. You cant do it in Erlang, either. I was assuming by intuitive you meant some sort of general thing that is language agnostic. If you're talking about intuition of how some specific language works, then you're wrong because nobody Im aware of knows exactly more than a small subset of any mainstream PL. I'm guessing you consider this trick intuitive because it's a common idiom in Java (which is mostly a symptom of `null`). Else it would probably not be intuitive for anyone. – Harold R. Eason Nov 22 '13 at 20:26
  • 1
    "but using bitwise | or & with multiple conditions could result in undesired behaviour. " This is just false. The semantics are laid out right [here](http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.22.2). – Harold R. Eason Nov 22 '13 at 20:35
  • @HaroldR.Eason, you are right, I should modify that, Its more like "short circuiting will be not be done" and expecting short circuiting on multiple conditions is desired behaviour IMO. – Habib Nov 22 '13 at 20:50
  • @Habib: Why is it desired behavior? The question is why or not should I use `&&`/`||` *everywhere* (like most Java code I've seen). – Dog Nov 22 '13 at 20:58
  • @Dog, Most of the time short circuiting is desired, You may see [this](http://stackoverflow.com/questions/9264897/reason-for-the-exsistance-of-non-short-circuit-logical-operators) question why non-short circuiting operators are useful. – Habib Nov 22 '13 at 21:06
  • @Habib: "Most of the time short circuiting is desired," I haven't experienced this desire. – Dog Nov 22 '13 at 21:14
  • @Dog, just added some more explanation, I hope its clear now. – Habib Nov 22 '13 at 21:21
  • @harold As you may have noticed, I'm talking about LISPs, specifically Scheme, CL and Clojure, where the short-circuit semantics are essential to many key language idioms. There as well as in C-style langs they are the second nature of any non-casual user and are by no means viewed as "tricks", as you put it. Null-checking is but a small example of their utility. – Marko Topolnik Nov 22 '13 at 21:58
  • 1
    @harold Your mentioning of VERY special cases like the IO monad is quite suspicious. Seems like you're pulling the last trick out of the hat to support the shaky fundaments of your position. – Marko Topolnik Nov 22 '13 at 22:01
  • @MarkoTopolnik: No. I was simple giving examples of languages that are similar to the other mainstream languages where you don't use short circuit evaluation. It was no longer clear what you're arguing about after your second comment. Maybe LISP has the same idiom, so what? – Harold R. Eason Nov 23 '13 at 02:00
  • @HaroldR.Eason You were using those languages as an argument to support your claim that short-circuit semantics are "terrible and counterintuitive". I used LISP, a language held in high regard by the worldwide CS community, and used as an exemplary language to teach FP, as counterargument. – Marko Topolnik Nov 23 '13 at 10:02
  • I don't know what you guys are arguing about, but the question is why I should use the longer operators *everywhere* (like what most Java code does). – Dog Nov 23 '13 at 16:56
  • 2
    @Dog You want short-circuiting semantics in >99% of use cases, therefore the conditional operators are a natural default. The usage of the plain boolean operators usually indicates inexperience, and only rarely is well-motivated by a specific requirement. – Marko Topolnik Nov 23 '13 at 18:41
  • @MarkoTopolnik: Very good comment. For now on I will use `|` 1% of the time and `||` 99% of the time. – Dog Nov 25 '13 at 17:48
3

|| is logical or, where | is the bitwise operation or. Same with && and &. Use && and || if you're in an if statement, and | or & if you're doing bit operations.

PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56
  • '|' is also the logical OR for boolean parameters, but it DOESN'T do short circuit evaluation, so even if the first operand is true, the second operand is evaluated. The same is true for '&' and the first operand returning false. – isnot2bad Nov 22 '13 at 19:12
  • A boolean is logically a single bit, so it's actually doing a bitwise operation. In order to complete the operation successfully, it has to know the actual value of both lvalue and rvalue. So, the fact it doesn't short circuit is a side effect of the boolean operation. – PaulProgrammer Nov 22 '13 at 19:15
  • In Java a `boolean` is an atomic Boolean value and has nothing to do with bitwise operations. – Marko Topolnik Nov 23 '13 at 12:46
  • @MarkoTopolnik: AtomicBoolean is atomic. What are you talking about? – Dog Nov 23 '13 at 16:20
  • 1
    @dog I am talking about the atomicity of the `boolean` value, as I have already made perfectly clear in the above comment. – Marko Topolnik Nov 23 '13 at 17:42
  • @MarkoTopolnik I'm lost, how does any of the content in this thread imply that I should only use `&&` and not `&`? I don't see what atomicity has to do with it at all. – Dog Nov 25 '13 at 17:41
  • If `|` is not logical, why can I use it on boolean? What definition of logical are you using? – Dog Nov 25 '13 at 17:45
  • Has to do with the view under the covers. boolean true = 1. boolean false = 0. `0 | 1 == 1`. In this case, and this case only, it is both bitwise and logical. – PaulProgrammer Nov 25 '13 at 17:47
  • @PaulProgrammer: So you're saying `|` *does* work for booleans. – Dog Nov 25 '13 at 17:50
  • Honestly, I haven't tried - my IDE doesn't complain. Whether or not it works, it may not document the _intent_ of the operation, and thus fails the "[principle of least astonishment](https://en.wikipedia.org/wiki/Principle_of_least_astonishment)" test. – PaulProgrammer Nov 25 '13 at 18:04
  • @Dog I was merely pointing out that the concept of *bitwise operation* is inapplicable to Java's `boolean` type, which is an atomic type covering the two truth values, `true` and `false`. Truth values have nothing to do with *bits*, which are numeric entities, and bringing in implementation details where the boolean values are represented by some *unspecified* bit patterns, has no place in a discussion about the Java language semantics. – Marko Topolnik Nov 25 '13 at 18:05
  • @MarkoTopolnik: The [link](http://docs.oracle.com/javase/specs/jls/se5.0/html/expressions.html#15.22.2) Harold posted seems to imply otherwise. " Boolean Logical Operators &, ^, and |" – Dog Nov 25 '13 at 18:17
  • I thought this wasn't about if it works or not (it does), but rather if it's a good idea. I propose it isn't. Your mileage may vary. – PaulProgrammer Nov 25 '13 at 18:21
  • It looks like you need to find a new argument. You claim `|` is not "logical", but the spec explicitly says that it is: "Boolean Logical Operators &, ^, and |". Yes the question is about whether it's a good idea, but your argument was that it doesn't work (or something). – Dog Nov 25 '13 at 18:24
  • Uncommon use then, which amounts to an astonishing use case. – PaulProgrammer Nov 25 '13 at 18:27
  • @Dog All I see there is that a "bitwise operator expression" is mentioned in passing (this term is otherwise not defined elsewhere), whereas the section title confirms what I am saying here: these are **boolean logical operators** when applied to boolean operands. – Marko Topolnik Nov 25 '13 at 18:55
  • @MarkoTopolnik: Your reasoning seems to be spread out in different comments to different answers. Perhaps you should write a detailed answer. The question is: "Why should I always use ||/&& instead of |/&?" – Dog Nov 25 '13 at 19:23
3

As has already been pointed out, && and || do short-circuit evaluation. & and |, with boolean operands, do the same operations but evaluate both operands regardless of the value of the first operand.

There are cases where it matters which you use, such as when the left operand is a pre-condition for exception-free evaluation of the right hand operand.

In most cases, it does not matter. I use && and || in those cases for readability, because that is the commoner choice. Using & or | with boolean operands would tend to make most Java programmers have to stop and think, and ask themselves whether there is some specific reason for it. I suspect it may be so common because of the inheritance from C and C++.

Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75
  • I'd say that, although it doesn't really matter in many cases, there is no motivation not to use the conditional operators as the default ones, and there clearly *is* motivation not to use the plain operators as the default. – Marko Topolnik Nov 23 '13 at 18:43
1

While you may get the "correct" result using the bit-wise operators, understand they do NOT represent the same thing. For instance, this works

public static void main(String[] args){
    int x = 5;
    int y = 9;
    System.out.println(x&y); // prints "1"
} 

However, this won't

public static void main(String[] args){
    int x = 5;
    int y = 9;
    System.out.println(x&&y); // Compile error: java: operator && cannot 
                              //                be applied to int,int
}

The reason you don't use bit-wise operators for boolean logic is so that it's clear what the code is trying to do (as well as knowing that it actually works). Bit-wise operators are for manipulating bit values, where as boolean operators are for evaluating first-order logic statements.

While not the same, it is along the same reasoning for using .equals() vs == for comparison -- You don't want readers guessing as to what you meant to do. It may work in some instances (like comparing constant, hard-coded strings with ==), but it is poor form because what it says is that you are asking for instance equality as opposed to value equality, which is usually implied. And using bit-wise operators implies you want to do bit manipulation, not first-order logic evaluation.

MadConan
  • 3,749
  • 1
  • 16
  • 27
  • Actually, there are times when `|` may be appropriate in Boolean logic, *if* one wants to call two methods and execute some code or keep looping if either returns true, but both methods must be called regardless. *Any such usage should have a comment at the code site explaining the need to have both methods run*. – supercat Nov 22 '13 at 20:04
  • 1
    @supercat: If I should comment when both operands need to be evaluated, then should I also comment when the right operand should only be evaluated if the left operand is `true` (as in Habib's example)? Both seem equally intuitive to me. – Dog Nov 22 '13 at 20:19
  • @Dog: I would guess that in ~90% of contexts where a Boolean-OR operator is used, evaluation of the right hand side would be a useless but harmless waste of time in cases where the left side returns true, in about ~9% it would be harmful, and in 1% it would be necessary. Commenting a usage of `||` for the 9% case is not nearly as important as commenting the usage of `|` for the 1% case, since someone who guesses that the usage represents the 90% case (where it doesn't matter) might inappropriately change the 1% case `|` to `||`, but would have no reason to change the 9% case `||` to `|` – supercat Nov 22 '13 at 20:56
  • @supercat Well put---except that you are grossly overestimating with 1% :) I don't remeber a single time in my whole coding career where I had to use the plain operator. There may have been one or two occasions along the way. – Marko Topolnik Nov 23 '13 at 18:46
  • @MarkoTopolnik: I wasn't trying to be numerically precise. My point was that cases where `|` would be correct and `||` wrong are much rarer than those where `||` would work and would be superior to `|` (whether it's a 90:1 or 9,000:1 ratio really doesn't matter). I don't particularly like code like `do {bool more = func1(); if (func2()) more=true;} while(more);` since if code sets `more` to false and then `true`, that would hint that code decided to stop and changed its mind. Further, absent a comment, it wouldn't be clear that `func2` would need to run even if `more` is true, and... – supercat Nov 23 '13 at 19:03
  • ...if one would need a comment in that situation, one might as well use `do {} while(func1() | func2()); // Need to run *both* functions on every pass through the loop, so use | rather than ||`. – supercat Nov 23 '13 at 19:05
  • @supercat I agree with everything you said, and am aware that your 1% was just an example. My comment's intention was to add on top of your argument that `|` is almost *never* used for good reason---the use cases just don't come up in real life. – Marko Topolnik Nov 23 '13 at 19:15
  • @MarkoTopolnik: So we're basically agreed that a comment is appropriate because someone who is reading the code might assume that `|` is "never" correct, even in those rare cases where it is? There are two main cases I recall using `|`: one was in a simulation where three routines, each of which affected things seen by the other two, had to run until all agreed that nothing had changed. Even if the first one didn't change anything on a given pass, the third one might have changed something on the *previous* pass which could cause the second to change something that the first would see... – supercat Nov 23 '13 at 19:33
  • ...on the *next* pass. Some people might have favored a flag approach, but I thought `|` was clearer. The other case involved processing of something similar to streams which supported a "rewind by up one item" method. I wanted to read four streams until I reached the end of whichever one happened to be shortest, and then rewind all four streams by one item. Perhaps a flag might have been better for that one (though it would still have needed a comment), but I think using `|` better conveys the idea that the four actions are independent. – supercat Nov 23 '13 at 19:37
  • @supercat Let's say I see a point in leaving a comment, but personally I tend to avoid them anyway because they a) get in the way when reading code; b) hold no guarantee that the statement therein is actually right, or up to date; c) it's hard to draw a line on where exactly you start commenting. – Marko Topolnik Nov 23 '13 at 19:38
  • @supercat And yes, I would use `|` in all cases you describe---the less syntactic units I must go through, the easier it is for me to get a 100% grip on the code. – Marko Topolnik Nov 23 '13 at 19:41
  • @MarkoTopolnik: I tend to comment rather sparsely, operating from the philosophy that code which can speak for itself is apt to be more readily understood than code which requires someone else to step in and speak on its behalf. Nonetheless, I think it's important to add comments or extra syntactic units in cases where someone reading the code might plausibly believe the code was intended to say something other than what it does. For example, `someDouble = int1/int2;` versus `someDouble=(int)(int1/int2);`, or `someDouble = (double)(float)0.1f;` versus `someDouble = 0.1f;`. – supercat Nov 23 '13 at 20:00
  • @supercat When looking for a bug, your attitude must anyway be to doubt everything, explained in a comment or not. On the other hand, never assume the original coder had no idea what he was doing when he wrote something---maybe he did even wander aimlessy, but the code may incidentally still work as written. `double d = i/j` may arise suspicion, perhaps, but then that's just something to give special attention to and not blindly "correct". When I was younger I got burnt several times by that cowboy attitude. – Marko Topolnik Nov 23 '13 at 20:04
1

Arguing that short circuit evaluation is mandatory because of performance is weak. You can make an argument that is almost as weak: that short circuit evaluation encourages extra nondeterminism and side channels. Random optimizations or random loss of nondeterminism/side channels, I'd prefer the latter.

The only remaining argument is this: If your code base relies on short circuit behaviour, e.g., the trick described by Habib (if (obj != null && obj.ID == 1)), then it may not be a good idea to start mixing in &, because programmers might get it confused with &&. i.e., if you use &/| everywhere, but only use && in a few places where you rely on short circuit evaluation, someone might make an error and put only &, it may be hard to spot. In this case, if you relied on && for performance instead of something like null checking, it may be harder to spot when someone accidentally puts & alone, since there would be no stacktrace.

Harold R. Eason
  • 563
  • 2
  • 9
  • Short-circuit evaluatian is not *mandatory*, but it's absolutely right as the default: it either doesn't hurt or provides a true performance/correctness benefit. I think you are underestimating the performance argument, though. Many boolean operands involve non-trivial calculation/waiting on external resources/synchronization, etc. I often find myself carefully ordering the clauses to delay the heavyweight call until proven necessary. – Marko Topolnik Nov 23 '13 at 19:19
1

Does using || and && improve my code in any way?

Let me demonstrate two examples on how the conditional boolean operators may improve your code. Compare

if (a != null && a.equals("b") || z != null && z.equals("y"))
  System.out.println("correct");

with

boolean b1 = a != null, b2 = z != null;
if (b1) b1 = b1 & a.equals("b");
if (b2) b2 = b2 & z.equals("y");
if (b1 | b2) System.out.println("correct");

which is the best way I can think of relying solely on the logical boolean operators.

Second, say you have two tests to perform: simpleTest() and heavyTest(), where the latter involves making an HTTP request and parsing the response. You have

if (simpleTest() & heavyTest()) System.out.println("success");
else throw new IllegalStateException();

and want to optimize it. What would you rather do, this:

if (simpleTest()) {
  if (heavyTest()) System.out.println("success");
  else throw new IllegalStateException("operation could not be completed");
} else throw new IllegalStateException("operation could not be completed"); 

this:

boolean b = simpleTest();
if (b) b = b & heavyTest());
if (b) System.out.println("success");
else throw new IllegalStateException("operation could not be completed");

or this:

if (simpleTest() && heavyTest()) System.out.println("success");
else throw new IllegalStateException();

Why should I always use || instead of | and && instead of &?

You shouldn't always use them, but you would do yourself a favor by making them your default because in 99.9% of uses they either don't hurt or make your code much better. Reserve the logical operators for that 0.1% of cases where you truly do need their semantics.


It has been mentioned elsewhere on this page that relying on the conditional evaluation of the right operand makes for counterintuitive code. I refuse to accept such a view on intuition because, by definition, intuition is a learned skill. It is a facility bestowed to you by evolution to recognize a pattern in situations you encounter often, and to quickly (and subconciously) cut through to the correct conclusions. One of the most important aspects of learning a language is acquiring the right intuitions. The argument that a language feature is bad because it is counterintuitive to someone who looks at it for the first time cannot be taken seriously.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • What's wrong with `if (a == null ? false : a.equals("b") | z == null ? false : z.equals("b")) System.out.println("correct");` or `if (a != null & b != null) if (a.equals("b") | & z.equals("y")) System.out.println("correct");` ? I personally find the last one the easiest to read and still pretty short. I would have never come up with the example you made. – Dog Nov 25 '13 at 20:46
  • And how do you add the equivalent of the overall `else` clause in your second idiom? And about the first one, maybe it's nicer to you personally, but most people who are well familiarized with `&&` and `||` still dread the Elvis operator as the pinnacle of non-readability. – Marko Topolnik Nov 25 '13 at 21:11
  • Oh, now I notice that your `if (a != null & b != null) if (a.equals("b") | & z.equals("y"))` isn't even correct: my version will print if *either* `a` is `"b"` *or* `z` is `"y"`. Your version will print only if *both* are non-null, and cannot be rewritten to match this. – Marko Topolnik Nov 25 '13 at 21:14
  • oops. okay then: `if ("b".equals(a) || "y".equals("z"))`. not general enough? `boolean correct; if (a != null) if (a.equals("b")) correct = true; if (z != null) if (z.equals("y")) correct = true; if (correct) System.out.println("correct");` – Dog Nov 25 '13 at 22:04
  • I'm not arguing that `||`/`&&` aren't useful, I'm asking why I should always use it. When I asked the question, I thought they were redundant because I didn't know that the shorter versions don't do short circuiting. – Dog Nov 25 '13 at 22:06
  • @Dog you shouldn't _always_ use them. However, the majority of the time we only care about answering one of two questions: 1) are _all_ of my conditions true? 2) are _any_ of my conditions true? In both cases, short-circuiting is desired because for 1) as soon as you find a condition that is `false`, you've answered your question and for 2) as soon as you find a condition that is `true` you've answered your question. Continuing to evaluate conditions after you've answered your question is fruitless. – DannyMo Nov 25 '13 at 22:28
  • @Dog Yes, the first one of your corrections is definitely just a special case. With the second one you have just slightly reorganized my example. And about "what is wrong" with them---they are long-winded, use a mutable local variable, harder to understand, harder to maintain, etc. – Marko Topolnik Nov 26 '13 at 06:32
0

In Java (and C/C++ if I remember correctly) the single "|" and "&" are bit-wise operators, not logical operators, they are used for completely different things.

You use the "&&" and "||" for boolean statements

You use the "&" and "|" for bit operations, given the following are binary numbers

tarares
  • 392
  • 4
  • 10
  • 27
0

dont make assumption so fast. It because this wont compile:

  static boolean f(boolean a) {
    boolean x = (true|a) ? a : x;
    return x;
  }

Bro.java:6: variable x might not have been initialized
    boolean x = (true|a) ? a : x;
                           ^

and this will:

  static boolean f(boolean a) {
    boolean x = (true||a) ? a : x;
    return x;
  }
Dude Bro
  • 1,152
  • 1
  • 10
  • 13
0

&& and || are short cut operators. For example:

A && B 

Condition B will not be evaluated if condition A is false

A || B

Condition B will not be evaluated if condition A is true

You should always use shortcut operators for multiple conditions evaluation. | or & are used for bit-wise operations.

csn
  • 376
  • 7
  • 18
  • 1
    There are some occasions where it's necessary to run multiple methods unconditionally and make a decision based upon the results. The non-short circuit operators can be useful for that, *if one expressly comments at the code site the need to call the methods unconditionally*. – supercat Nov 22 '13 at 20:07