Since Checkstyle 3.2
The complexity is equal to the number of decision points + 1
.
Decision points:
if
, while
, do
, for
,
?:
, catch
, switch
, case
statements.
&&
and ||
in the body of target.
when
expression in case labels, also known as guards.
By pure theory level 1-4 is considered easy to test, 5-7 OK, 8-10 consider re-factoring to ease testing, and 11+ re-factor now as testing will be painful.
When it comes to code quality measurement by this metric level 10 is very good level as a ultimate target (that is hard to archive). Do not be ashamed to have complexity level 15 or even higher, but keep it below 20 to catch really bad-designed code automatically.
Please use Suppression to avoid violations on cases that could not be split in few methods without damaging readability of code or encapsulation.
name | description | type | default value | since |
---|---|---|---|---|
max | Specify the maximum threshold allowed. | int | 10 |
3.2 |
switchBlockAsSingleDecisionPoint | Control whether to treat the whole switch block as a single decision point. | boolean | false |
6.11 |
tokens | tokens to check | subset of tokens LITERAL_WHILE , LITERAL_DO , LITERAL_FOR , LITERAL_IF , LITERAL_SWITCH , LITERAL_CASE , LITERAL_CATCH , QUESTION , LAND , LOR , LITERAL_WHEN . | LITERAL_WHILE , LITERAL_DO , LITERAL_FOR , LITERAL_IF , LITERAL_SWITCH , LITERAL_CASE , LITERAL_CATCH , QUESTION , LAND , LOR , LITERAL_WHEN . | 3.2 |
To configure the check:
<module name="Checker"> <module name="TreeWalker"> <module name="CyclomaticComplexity"/> </module> </module>
Example:
class CyclomaticComplexity { // Cyclomatic Complexity = 11 int a, b, c, d, n; public void foo() { // 1, function declaration if (a == 1) { // 2, if fun1(); } else if (a == b // 3, if && a == c) { // 4, && operator if (c == 2) { // 5, if fun2(); } } else if (a == d) { // 6, if try { fun4(); } catch (Exception e) { // 7, catch } } else { switch(n) { case 1: // 8, case fun1(); break; case 2: // 9, case fun2(); break; case 3: // 10, case fun3(); break; default: break; } } d = a < 0 ? -1 : 1; // 11, ternary operator } }
To configure the check with a threshold of 4 and check only for while and do-while loops:
<module name="Checker"> <module name="TreeWalker"> <module name="CyclomaticComplexity"> <property name="max" value="4"/> <property name="tokens" value="LITERAL_WHILE, LITERAL_DO"/> </module> </module> </module>
Example:
class CyclomaticComplexity { // Cyclomatic Complexity = 5 int a, b, c, d; public void foo() { // 1, function declaration while (a < b // 2, while && a > c) { fun(); } if (a == b) { do { // 3, do fun(); } while (d); } else if (c == d) { while (c > 0) { // 4, while fun(); } do { // 5, do-while fun(); } while (a); } } }
To configure the check to consider switch-case block as one decision point.
<module name="Checker"> <module name="TreeWalker"> <module name="CyclomaticComplexity"> <property name="switchBlockAsSingleDecisionPoint" value="true"/> </module> </module> </module>
Example:
class CyclomaticComplexity { // Cyclomatic Complexity = 11 int a, b, c, d, e, n; public void foo() { // 1, function declaration if (a == b) { // 2, if fun1(); } else if (a == 0 // 3, if && b == c) { // 4, && operator if (c == -1) { // 5, if fun2(); } } else if (a == c // 6, if || a == d) { // 7, || operator fun3(); } else if (d == e) { // 8, if try { fun4(); } catch (Exception e) { // 9, catch } } else { switch(n) { // 10, switch case 1: fun1(); break; case 2: fun2(); break; default: break; } } a = a > 0 ? b : c; // 11, ternary operator } }
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.metrics