8

Our team's Java Coding Guideline says:

Avoid using "!" in if statement as much as possible.

I have asked other colleagues, but no one gave me clear ideas why, because the guideline was created a long time ago and the author might have left our company.

Do you have any idea?

kenju
  • 5,866
  • 1
  • 41
  • 41
  • 4
    The only reason I can think might have to do with readability – MadProgrammer Aug 21 '15 at 02:53
  • @MadProgrammer Thanks. Um... I firstly thought using "!" is simpler and easy to read... is it the matter of sense or way of thinking? – kenju Aug 21 '15 at 02:55
  • 3
    I think `if (notTrue) {}` is more easy to read than `if (!true) {}` – Antony Dao Aug 21 '15 at 02:56
  • 1
    There will be no valid reason to stop using `!` in codes other than readability (*that too when you over used*). There are obvious cases to use it. But use it whenever you need it only. – Suresh Atta Aug 21 '15 at 02:57
  • 1
    @Kenju There's no "complying" reason (from a performance point of view), so the only thing I can think of is the author had a preferred bias towards not using them. This could be for readability, beyond `!` itself, as it would structure the code in a particular way. But that's just guess work – MadProgrammer Aug 21 '15 at 02:57
  • 1
    I find !quite confusing. Because you have to *Remember. Where as I can see blah == true. Definitely personal preference – FirebladeDan Aug 21 '15 at 02:58
  • @Antony Now I see what MadProgrammer said. Do you think is the guideline usual and standard in Java world? – kenju Aug 21 '15 at 02:58
  • 2
    http://stackoverflow.com/questions/4775379/using-not-operator-in-if-conditions – Martyn Davis Aug 21 '15 at 03:00
  • 1
    @Kenju - You're going to have style rules at any company. If you don't your principal/senior dev will want you to provide something he's used to. However, looks like industry is getting better with things like stylecop and such – FirebladeDan Aug 21 '15 at 03:02
  • I think I got the point... thank you all. – kenju Aug 21 '15 at 03:07
  • You could use `if (someBoolean&false)` to avoid `!` :-). – Mathias Begert Aug 21 '15 at 05:32

7 Answers7

11

With the information provided, this calls for some speculation. One possible reason is that the intent was not for an if-statement by itself but for an if-else statement. In that case, I can see where you might say that you should reverse the cases so that you don't have the extra operation of the negation. Instead of

if (! boolVar) {
  // Something
} else {
  // Something else
}

you might prefer

if (boolVar) {
  // Something else
} else {
  // Something
}

Whether this is worth it or not is probably more a matter of taste and standardization than anything else.

Brick
  • 3,998
  • 8
  • 27
  • 47
6

The rule is likely an adaptation from Robert Martin's Clean Code, page 302:

Negatives are just a bit harder to understand than positives. So, when possible, conditionals should be expressed as positives. For example:

if(buffer.shouldCompact())

is preferable to

if(!buffer.shouldNotCompact())

As an example, suppose you're creating a validator that requires two things to be false for the entity to be valid:

  • The entity must not have been created within the last 12 hours, and
  • The entity's bank account total sum must not exceed $50,000.

Naturally the idea would be to write two methods for this:

boolean isCreatedWithinLastTwelveHours(BankAccount account)
boolean hasMoreThanTotalSumCap(BankAccount account)

...at which point, you then invoke these as:

boolean newAccount = isCreatedWithinTheLastTwelveHours(account);
boolean highEndAccount = hasMoreThanTotalSumCap(account);

if(!newAccount && !highEndAccount) { // ... other logic

// The more astute would use DeMorgan's law in an effort to make this more readable

if(!(newAccount || highEndAccount)) { // other logic

Well...wouldn't it be nicer if you just said what they weren't instead?

boolean isNotCreatedWithinLastTwelveHours(BankAccount account)
boolean hasLessThanTotalSumCap(BankAccount account)

That'd make the expression a bit more concise:

if(notNewAccount && notHighEndAccount) { // .. carry on!
Community
  • 1
  • 1
Makoto
  • 104,088
  • 27
  • 192
  • 230
1

Of course "!" can be used when you like. There is no "unless" in java and you have no other choices in some conditions.

user2219372
  • 2,385
  • 5
  • 23
  • 26
1

Looks like yet-another-useless-rule. Generally speaking, there are no absolute terms in this scenario, true that if you are in a if-else clause then possibly it is better to write

if(myCondition) {
    doThis()
} else {
    doSomethingElse()
}

Instead of

if(!myCondition) {
   doSomethingElse()
} else {
   doThis()
}

However, that said, in some scenarios is actually quite ok to use the negation operator, particularly if no else clause is provided, example

if (!tokenDoesCompute()) {
   throw InvalidTockenException("Whatever")
}

And actually in that scenario, using "!" makes quite a bit of sense for me.

Finally, if no one can really explain WHY the rule is there, maybe it is time to remove it, the only good reason I could find for it would be to provide consistency regarding the code style.

Juan Antonio Gomez Moriano
  • 13,103
  • 10
  • 47
  • 65
  • I'm sure that the if-then-else scenario is the reason. In a case like that, I definitely prefer `if(expr)` to `if(!expr)`. But it looks like someone took that one case and either went overboard turning it into a simple rule, or just got extremely sloppy and didn't explain what they meant. I've seen this sort of thing happen way too often, though. _Sigh_.............. – ajb Aug 21 '15 at 04:14
  • 3
    Your second example makes no sense "if(!tokenDoesNotCompute)" so token does compute, then throw an exception? This proves that the negation operator can be confusing sometimes... :). – Mathias Begert Aug 21 '15 at 05:16
  • @MathiasBegert you are absolutely right, I fixed it. (thanks!) – Juan Antonio Gomez Moriano Aug 31 '15 at 22:53
1

Okay, I answer my own question. As other say, maybe this is written for the readability.

In The Art of Readable Code (p. 72) says:

Prefer dealing with the positive case first instead of the negative-e.g., if(debug) instead of if(!debug)

I found below post as well:

  • Readable Code - Remove Checking null

    bool func(String name)
    {
        if ( (name != null) && (name.equals("true") ) {
            //...
        } else {
            //...
        }
    }
    

    bool func(String name)
    {
        if ( "true".equals(name) ) {
           //...
        } else {
            //...
        }
    }
    
Tom
  • 16,842
  • 17
  • 45
  • 54
kenju
  • 5,866
  • 1
  • 41
  • 41
0

Ofcourse you can use the negation operator ! whenever you like.

However, if you have a situation where you have to write some actions in both if and else block then the following is more readable :

if(status){
//do something
}
else{
//do something else
}

than

if(!status){
//do something
}
else{
//do something else
}

But if you have situation where you only need to perform certain actions based on just one condition, i.e. if you have only an if block & no else block, then it is reasonably fine to use ! in if

0

I haven't seen anyone else suggest this, which is probably because they hate it as much as I do, but I'm showing it for completeness.

// Using not operator (preferred)
if (! someTest) { ... }

// Using compact not operator (kind of hides it)
if (!someTest) { ... }

// Comparing to false (ok, explicitly states what you want)
if (someTest == false) { ... }

// Comparing to true (a bit obscure)
if (someTest != true) { ... }

They all do the same, but please keep using !, just make sure you add a space after it, so it's easier to see.

Andreas
  • 154,647
  • 11
  • 152
  • 247