Getting confused with == and = in "if" statement
Asked Answered
U

5

12

I know that we cant use assignment operator in if statements in java as we use in any other few languages.

that is

            int a;

            if(a = 1) {  } 

will give a compilation error.

but the following code works fine, how?

           boolean b;

           if(b = true) {   }

EDIT : Is this the exception to rule that assignment cant be used in if statement.

Upanddown answered 6/3, 2010 at 20:18 Comment(5)
It's not a bad idea to get in the habit of putting the constant first in your if statements.... That is: if (true == b) {} and if (1 == a) {} This habit guarantees that the compiler will smack you if you write = instead of ==.Mesonephros
@Ollie: opinions widely differ on that one. As far as readability is concerned, this is a bad idea. Furthermore, it offers no benefit in languages such as Java since no confusion can arise here. I mean, nobody ever writes a test as if (a == true), right?Daiquiri
@Konrad. You're right in Java, but for this C retread who works in PERL and some other languages, it's saved me lots of times.Mesonephros
Doesn't work in a huge variety of cases, like if ( $a == $b ). Horrible to read, nobody says '5 is a'. It's easier to just be more careful when writing if conditions, IMO.Geulincx
@Ollie most compilers these days have an option to warn you if you write if(foo = x) or something like that.Strother
E
41

Because the "result" of an assignment is the value assigned... so it's still a boolean expression in the second case. if expressions require the condition to be a boolean expression, which is satisfied by the second but not the first. Effectively, your two snippets are:

int a;

a = 1;
if (a) { }

and

boolean b;

b = true;
if (b) { }

Is it clear from that expansion that the second version will compile but not the first?

This is one reason not to do comparisons with true and false directly. So I would always just write if (b) instead of if (b == true) and if (!b) instead of if (b == false). You still get into problems with if (b == c) when b and c are boolean variables, admittedly - a typo there can cause an issue. I can't say it's ever happened to me though.

EDIT: Responding to your edit - assignments of all kinds can be used in if statements - and while loops etc, so long as the overall condition expression is boolean. For example, you might have:

String line;
while ((line = reader.readLine()) != null)
{
    // Do something with a line
}

While I usually avoid side-effects in conditions, this particular idiom is often useful for the example shown above, or using InputStream.read. Basically it's "while the value I read is useful, use it."

Edo answered 6/3, 2010 at 20:20 Comment(7)
Are you sure there are an extra pair of parentheses in the last example? I thought assignment has the last precedence in Java...Rameriz
@Carlos: Good catch. Maybe I'm so used to deliberately putting it in that I've never tried without :)Edo
I usually think of that idiom (and use it when the analogy fits) in terms of the iterator's hasNext and next methods - it's basically implementing a combination of those for something that isn't explicitly an iterator (and I sure wish readers had implementation of that interface added in later versions).Fully
Additionally, in some languages (C, C++) an integer can be substituted for a boolean value, with 0 being false and non-0 being true. Which widely increases the chances of the =/== bug.Bernat
@mtruesdell: Indeed, although I believe most C and C++ compilers will warn you unless you have an extra pair of parentheses to reinforce that it's deliberate... at least if you have warnings turned up high enough.Edo
You can avoid the danger of if(b == c) by instead using something like if(!(b ^ c)).Lutanist
@ILMTitan: Yes, but if you're thinking enough about it to write that, chances are you'll get it right anyway :)Edo
Z
10

For if you need an expression that evaluates to boolean. b = true evalueates to boolean but a = 1 evaluates to int as assignments always evaluate to the assigned values.

Zirconium answered 6/3, 2010 at 20:20 Comment(0)
S
1

The reason the second code works okay is because it is assigning 'b' the value of true, and then comparing to see if b is true or false. The reason you can do this is because you can do assignment operators inside an if statement, AND you can compare against a boolean by itself. It would be the same as doing if(true).

Sweat answered 6/3, 2010 at 20:21 Comment(0)
B
1

In java, you don't have implicit casting. So non-boolean values or not automatically transformed to booleans.

In the first case, the result of the statements is an int, which is non-boolean, which will not work. The last case, the result is boolean, which can be evaluated in an if-statement.

Boggers answered 6/3, 2010 at 20:23 Comment(0)
B
1

The rule is not that "assignment can't be used in an if statement", but that "the condition in an if statement must be of type boolean". An assignment expression produces a value of the type being assigned, so Java only permits assignment in an if statement if you're assigning a boolean value.

This is a good reason why the style if (foo == true) should be avoided, and instead simply write if (foo).

Bibb answered 6/3, 2010 at 20:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.