views:

673

answers:

7

Sorry, I'm new to Java, so this question might be unclear.

I have been recently dealing with enclosing a try and catch statement in a while loop, because I wanted to make sure that getting input was enclosed from the rest of the program. I have come across a problem where using an exclamation mark in front of a variable in the while conditions (e.g. while (!done)) instead of using = false (e.g. while (done = false)) changes the way my program runs.

The former (!done) results in the try and except statements running as expected. The latter (done = false) does not, simply skipping them and moving on to the next part of the code.

I was under the impression that ! before a var meant the same thing as var = false. Am I mistaken?

Here's an example:

import java.util.Scanner;

public class TestOne {
    public static void main(String args[]) {
     Scanner input = new Scanner(System.in);
     int num;
     boolean inputDone = false;
     while (!inputDone) {
      try {
       System.out.print("Enter in a number here: ");
       num = input.nextInt();
       inputDone = true;
      }
      catch (Exception e) {
       System.out.println(e);
       System.exit(0);
      }
     }
     System.out.println("Success!");
    }
}

Currently, compiling and running the program will go smoothly: it will prompt me for a number, typing in a letter or really long number causes it to print out the exception type and exit, or typing in a normal number causes it to print Success!

On the other hand, if I were to replace !inputDone with inputDone = false, it simply prints out Success! when I run the program.

Can anyone explain the difference to me between the ! and the = false statements in a while loop?

+4  A: 

The statement x = false is an assignment - you are setting x to false. The statements x == false and !x are the same, however. The statement x == false compares x to false and will be true if the value of x is false and false if the value of x is true. The statement !x will result in the negation of the value of x.

In your code, if you replace while (!inputDone) with while(inputDone == false), you will get the expected behavior.

Thomas Owens
Ohh, haha. Wow, I can't believe I missed that. Thanks!
Mana
+14  A: 

Note the difference between done = false and done == false. The first one assigns done to be false and evaluates as false, the second one compares done with false and is exactly identical to !done.

So if you use:

while (done = false)
{
 // code here
}

Then done is set to false and the code within the while loop doesn't run at all.

Joren
Thanks. That's the second error in recent times I've forgotten about that second exclamation mark.
Mana
err, not exclamation mark; equals sign. LOL.
Mana
@Mana: if you get out of the (BAD) habit of explicitly comparing booleans with '==', you won't make this mistake.
Stephen C
+2  A: 
x = false

assigns x the value "false" to x. while() then evaluates x, which is false so it doesn't enter the loop

while (!x)

means "as long as !x is true, continue entering the loop". since !x means "the opposite of x" as long as x is false, the loop will continue

Mike
+2  A: 

"while(done = false)" is equals to "done=false; while(done)"

It should be written as "while(done == false)" or "while(false == done)".

But still , !done is the most readable code, it say "NOT DONE"

Dennis Cheung
It should be written as `while (!done) {`.
Tom Hawtin - tackline
writing "while (done == false) ..." works best for me. I tend to overlook those pesky exclamation marks.
Thorbjørn Ravn Andersen
+2  A: 

You need to use == instead of = for comparisons.

JG
+1  A: 

As many others have pointed out, you have typoed ==. More interesting are the issues surrounding this.

For language designed: Encouraging side-effects in expressions is bad. Using the symbol == to represent mathematical = is not a good choice.

In terms of readability, !done reads much better than done == false - we want "not done" (better, IMO, would be "until done" instead of "while not done"). Although (perpetual) newbies often write the redundant someCondition == true.

It is a good idea to make variables final, although clearly not feasible in this situation. However, we can remove the flag entirely by using a break statement. A minority opinions follows a Single Entry Single Exit (SESE) rule, whereby break is banned, whcih would make this example more tricky (you'd need a test to see if the text was a valid int, or in this case, move the body into the loop.

Tom Hawtin - tackline
A: 

Other answers have alluded to the fact that writing "x == false" and "x == true" are bad style. There are three reasons for this:

  • Conciseness: assuming that you are in a context where a boolean is required, and "x" is a boolean, it is less characters to write "x" than "x == true", or "!x" than "x == false".
  • Convention: seasoned programmers in Java (or C, C++, C# and most other languages) expect to see "x" rather than "x == true", and "!x" rather than "x == false".
  • Robustness: in Java the conditional and loop statements all require a boolean valued expression in the condition. If "y" is not a boolean, then a typo of the form "if (y = foo) {" will give a compilation error in Java. But if "y" is a boolean then "if (y = foo) {" does not give a compilation error. Hence, by avoiding "==" for booleans you avoid setting yourself up for a whole raft of bugs resulting from typos.
Stephen C