Search code examples
javaparentheses

Recognizing Redundant parenthesis


Usually it is easy to spot unnecessary parenthesis in your program but I am having a little confusion about using parenthesis in if statements.

public class TestClass {
    void method(String sectionName) {
        if ("Content".equals(sectionName) || "Overview".equals(sectionName)
                // suppression list
                || (!"AbbreviationAsWordInName".equals(sectionName)
                        && !"AbstractClassName".equals(sectionName)
                        )) {
             System.out.println();
         }
    }
}

I feel the parenthesis on line 5 (before !"AbbreviationAsWordInName") are unnecessary. Now the problem is that usually I could have tested the code and then come to an conclusion but right now I am fixing some bug in an open source program and that plugin in turn is used by many other programs, so I am getting little confused.

More examples-

if (active == (forward ? past : future) &&
    ((increasing && switchOnIncrease) || (!increasing && switchOnDecrease))) 

In the example above I feel on line 2 unnecessary parenthesis are there.
Another example-

else if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {}

I think there are extra parenthesis in the example above, it should be like-

else if (c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F') {}

Please help me with a solid solution.


Solution

  • If you format this if statement into a one-liner you will have better clarity of whats is actually going on in the statement.

    if ("Content".equals(sectionName) || "Overview".equals(sectionName) || (!"AbbreviationAsWordInName".equals(sectionName) && "AbstractClassName".equals(sectionName) )) {
    

    Now if you look at it and break this down into segments you will see that there are only 3 conditions that need to be meet.

    • 1st. if ("Content".equals(sectionName))
    • 2nd. if ("Overview".equals(sectionName))
    • 3rd. if (!"AbbreviationAsWordInName".equals(sectionName) && "AbstractClassName".equals(sectionName) )

    While it may be correct to leave the parenthesis out on the 3rd condition as after the || and before closing parenthesis, the code will be evaluated as a single condition - for anyone looking at the 3rd condition these 'redundant' parenthesis actually provide a little clarity as to what forms part of this condition. There is no doubt that both of these "AbbreviationAsWordInName".equals(sectionName) and "AbstractClassName".equals(sectionName) have to bee meet in order to evaluate to true.

    If you left this parenthesis out, one could get confused about whether these two form part of a single condition or not.

    Also its worth mentioning that there is a level of precedence in logical expressions like so: src enter image description here

    Just like arithmetic operators, logical operators have an order of operations: first NOT, then AND, then OR. If you leave out parenthesis in logical expressions in a place where they are actually needed (without even noticing it) this could result in a logically different expression. Always use parentheses to make sure the computer evaluates the conditions in the expected order.

    I guess at the end of the day (at least in my opinion) it's better to clearly segregate logical conditions so they are easier to understand but also extra parentheses, just like indentations, whitespace, and other styles standards, help visually organize the code in a logical way.