3

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 variable 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. 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?

dplante
  • 2,445
  • 3
  • 21
  • 27
akbiggs
  • 34,001
  • 6
  • 25
  • 36

8 Answers8

17

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.

Tomas Aschan
  • 58,548
  • 56
  • 243
  • 402
Joren
  • 14,472
  • 3
  • 50
  • 54
  • Thanks. That's the second error in recent times I've forgotten about that second exclamation mark. – akbiggs Sep 20 '09 at 14:38
  • 3
    @Mana: if you get out of the (BAD) habit of explicitly comparing booleans with '==', you won't make this mistake. – Stephen C Sep 21 '09 at 01:34
4

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
  • 114,398
  • 98
  • 311
  • 431
3

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

João Silva
  • 89,303
  • 29
  • 152
  • 158
2

The expression:

x = false

means assign x the value false.

After this happens in your while(), it then evaluates x, which is false so it doesn't enter the loop at all.

On the other hand:

while (!x)

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

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Mike
  • 58,961
  • 76
  • 175
  • 221
2

"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 C
  • 24,511
  • 12
  • 71
  • 99
2

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
  • 145,806
  • 30
  • 211
  • 305
1

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.
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
0

Many have already pointed out your misuse of = vs. ==. I would like to point out that running a static code analysis tool like Findbugs would have found this for you right away.

See QBA: Method assigns boolean literal in boolean expression

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Jeff Olson
  • 6,323
  • 2
  • 22
  • 26