Since Checkstyle 3.4
Checks if unnecessary parentheses are used in a statement or expression. The check will flag the following with warnings:
return (x); // parens around identifier return (x + 1); // parens around return value int x = (y / 2 + 1); // parens around assignment rhs for (int i = (0); i < 10; i++) { // parens around literal t -= (z + 1); // parens around assignment rhs boolean a = (x > 7 && y > 5) // parens around expression || z < 9; boolean b = (~a) > -27 // parens around ~a && (a-- < 30); // parens around expression
The check is not "type aware", that is to say, it can't tell if parentheses are unnecessary based on the types in an expression. The check is partially aware about operator precedence but unaware about operator associativity. It won't catch cases such as:
int x = (a + b) + c; // 1st Case boolean p = true; // 2nd Case int q = 4; int r = 3; if (p == (q <= r)) {}
In the first case, given that a, b, and c are all
int
variables, the parentheses around a + b
are not needed.
In the second case, parentheses are required as q, r are
of type int
and p is of type boolean
and removing parentheses will give a compile-time error. Even if q
and r were boolean
still there will be no violation
raised as check is not "type aware".
The partial support for operator precedence includes cases of the following type:
boolean a = true, b = true; boolean c = false, d = false; if ((a && b) || c) { // violation, unnecessary paren } if (a && (b || c)) { // ok } if ((a == b) && c) { // violation, unnecessary paren } String e = "e"; if ((e instanceof String) && a || b) { // violation, unnecessary paren } int f = 0; int g = 0; if (!(f >= g) // ok && (g > f)) { // violation, unnecessary paren } if ((++f) > g && a) { // violation, unnecessary paren }
To configure the check:
<module name="Checker"> <module name="TreeWalker"> <module name="UnnecessaryParentheses"/> </module> </module>
Which results in the following violations:
class Example1 { public int square(int a, int b) { // violation below, 'Unnecessary parentheses around assignment right-hand side' int square = (a * b); // violation below, 'Unnecessary parentheses around identifier 'square'' return (square); } int sumOfSquares = 0; public void sumOfSquares() { // violation below, 'Unnecessary parentheses around literal '0'' for (int i = (0); i < 10; i++) { // violation below, 'Unnecessary parentheses around assignment right-hand side' int x = (i + 1); sumOfSquares += (square(x,x)); // 2 violations } } List<String> myList = List.of("a1", "b1", "c1"); public void filter() { myList.stream() // violation below, 'Unnecessary parentheses around lambda value' .filter((s) -> s.startsWith("c")) .forEach(System.out::println); } int a = 10, b = 12, c = 15; boolean x = true, y = false, z = true; public void test() { // 3 violations below if ((a >= 0 && b <= 9) || (c >= 5 && b <= 5) || (c >= 3 && a <= 7)) { return; } // violation below, 'Unnecessary parentheses around expression' if ((-a) != -27 && b > 5) { return; } if (x == (a <= 15)) { return; } if (x == (y == z)) { return; } } }
To configure the check to detect unnecessary parentheses around bitwise inclusive OR
'|'
, bitwise AND '&'
, bitwise exclusive OR
'^'
:
<module name="Checker"> <module name="TreeWalker"> <module name="UnnecessaryParentheses"> <property name="tokens" value="BOR, BAND, BXOR" /> </module> </module> </module>
Example:
class Example2 { void method() { int x = 9, y = 8; // violation below, 'Unnecessary parentheses around expression' if (x >= 0 ^ (x <= 8 & y <= 11) ^ y >= 8) { return; } if (x >= 0 ^ x <= 8 & y <= 11 ^ y >= 8) { return; } // violation below, 'Unnecessary parentheses around expression' if (x >= 0 || (x <= 8 & y <= 11) && y >= 8) { return; } if (x >= 0 || x <= 8 & y <= 11 && y >= 8) { return; } if (x >= 0 & (x <= 8 ^ y <= 11) & y >= 8) { return; } } }
All messages can be customized if the default message doesn't suit you. Please see the documentation to learn how to.
com.puppycrawl.tools.checkstyle.checks.coding