Getting confused with == and = in "if" statement
Solution 1
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."
Solution 2
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.
Solution 3
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).
Solution 4
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)
.
Solution 5
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.
GuruKulki
Updated on June 05, 2022Comments
-
GuruKulki almost 2 years
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.
-
user85421 about 14 yearsAre you sure there are an extra pair of parentheses in the last example? I thought assignment has the last precedence in Java...
-
Jon Skeet about 14 years@Carlos: Good catch. Maybe I'm so used to deliberately putting it in that I've never tried without :)
-
Carl about 14 yearsI 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).
-
lbergnehr about 14 yearsAdditionally, 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.
-
Jon Skeet about 14 years@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.
-
ILMTitan about 14 yearsYou can avoid the danger of if(b == c) by instead using something like if(!(b ^ c)).
-
Jon Skeet about 14 years@ILMTitan: Yes, but if you're thinking enough about it to write that, chances are you'll get it right anyway :)