Index of the code metrics available out of the box to Java rule developers.
Index of code metrics Access to Foreign Data (ATFD)Operation metric, class metric. Can be computed on classes, enums and concrete operations.
DescriptionNumber of usages of foreign attributes, both directly and through accessors. High values of ATFD (> 3 for an operation) may suggest that the class or operation breaks encapsulation by relying on the internal representation of the classes it uses instead of the services they provide.
ATFD can be used to detect God Classes and Feature Envy. [Lanza05]
Class Fan Out Complexity (CLASS_FAN_OUT)Operation metric, class metric. Can be computed on classes, enums and concrete operations.
DescriptionThis counts the number of other classes a given class or operation relies on. Classes from the package java.lang
are ignored by default (can be changed via options). Also primitives are not included into the count.
import java.util.*;
import java.io.IOException;
public class Foo { // total 8
public Set set = new HashSet(); // +2
public Map map = new HashMap(); // +2
public String string = ""; // from java.lang -> does not count by default
public Double number = 0.0; // from java.lang -> does not count by default
public int[] intArray = new int[3]; // primitive -> does not count
@Deprecated // from java.lang -> does not count by default
@Override // from java.lang -> does not count by default
public void foo(List list) throws Exception { // +1 (Exception is from java.lang)
throw new IOException(); // +1
}
public int getMapSize() {
return map.size(); // +1 because it uses the Class from the 'map' field
}
}
Options
includeJavaLang
: Also include classes from the package java.lang
Operation metric. Can be calculated on any non-abstract operation.
DescriptionCognitive complexity is a measure of how difficult it is for humans to read and understand a method. Code that contains a break in the control flow is more complex, whereas the use of language shorthands doesnât increase the level of complexity. Nested control flows can make a method more difficult to understand, with each additional nesting of the control flow leading to an increase in cognitive complexity.
Information about Cognitive complexity can be found in the original paper here: CognitiveComplexity
The rule CognitiveComplexity
by default reports methods with a complexity of 15 or more. These reported methods should be broken down into less complex components.
There is an increment for each of the following:
if
, else if
, else
, ternary operatorswitch
for
, foreach
while
, do while
catch
goto LABEL
, break LABEL
, continue LABEL
The following structures increment the nesting level:
if
, else if
, else
, ternary operatorswitch
for
, foreach
while
, do while
catch
The following structures receive a nesting increment commensurate with their nested depth inside nested structures:
if
, ternary operatorswitch
for
, foreach
while
, do while
catch
class Foo {
void myMethod () {
try {
if (condition1) { // +1
for (int i = 0; i < 10; i++) { // +2 (nesting=1)
while (condition2) { } // +3 (nesting=2)
}
}
} catch (ExcepType1 | ExcepType2 e) { // +1
if (condition2) { } // +2 (nesting=1)
}
} // Cognitive Complexity 9
}
Cyclomatic Complexity (CYCLO)
Operation metric. Can be calculated on any non-abstract operation.
DescriptionNumber of independent paths through a block of code [Lanza05]. Formally, given that the control flow graph of the block has n
vertices, e
edges and p
connected components, the cyclomatic complexity of the block is given by CYCLO = e - n + 2p
[McCabe76]. In practice it can be calculated by counting control flow statements following the standard rules given below.
The standard version of the metric complies with McCabeâs original definition:
if
, case
, catch
, throw
, do
, while
, for
, break
, continue
) and conditional expression (?:
) [Sonarqube]. Notice switch cases count as one, but not the switch itself: the point is that a switch should have the same complexity value as the equivalent series of if
statements.else
, finally
and default
donât count;&&
, ||
) in the guard condition of a control flow statement. Thatâs because Java has short-circuit evaluation semantics for boolean operators, which makes every boolean operator kind of a control flow statement in itself.class Foo {
void baseCyclo() { // Cyclo = 1
highCyclo();
}
void highCyclo() { // Cyclo = 10
int x = 0, y = 2;
boolean a = false, b = true;
if (a && (y == 1 ? b : true)) { // +3
if (y == x) { // +1
while (true) { // +1
if (x++ < 20) { // +1
break; // +1
}
}
} else if (y == t && !d) { // +2
x = a ? y : x; // +1
} else {
x = 2;
}
}
}
}
Options
CycloVersion#IGNORE_BOOLEAN_PATHS
: Boolean operators are not counted, nor are empty fall-through cases in switch
statements. You can use this option to get results similar to those of the old StdCyclomaticComplexityRule
, which is to be replaced.CycloVersion#CONSIDER_ASSERTS
: Assert statements are counted as if they were if (..) throw new AssertionError(..)
. Compatible with IGNORE_BOOLEAN_PATHS
.Operation metric, class metric. Can be calculated on any of those nodes.
DescriptionSimply counts the number of lines of code the operation or class takes up in the source. This metric doesnât discount comments or blank lines. See also NCSS.
Operation metric, class metric. Can be calculated on any of those nodes.
DescriptionNumber of statements in a class or operation. Thatâs roughly equivalent to counting the number of semicolons and opening braces in the program. Comments and blank lines are ignored, and statements spread on multiple lines count as only one (e.g. int\n a;
counts a single statement).
The standard version of the metric is based off JavaNCSSâs version
[JavaNcss]:
if
, else
, while
, do
, for
, switch
, break
, continue
, return
, throw
, synchronized
, catch
, finally
.for
loop initializers) or statement expression. We count variables declared on the same line (e.g. int a, b, c;
) as a single statement.COUNT_IMPORTS
option.import java.util.Collections; // +0
import java.io.IOException; // +0
class Foo { // +1, total Ncss = 12
public void bigMethod() // +1
throws IOException {
int x = 0, y = 2; // +1
boolean a = false, b = true; // +1
if (a || b) { // +1
try { // +1
do { // +1
x += 2; // +1
} while (x < 12);
System.exit(0); // +1
} catch (IOException ioe) { // +1
throw new PatheticFailException(ioe); // +1
}
} else {
assert false; // +1
}
}
}
Options
NcssVersion#COUNT_IMPORTS
: Import and package statements are counted as well. This version fully complies with JavaNCSS.Operation metric. Can be computed on any non-abstract operation.
DescriptionNumber of acyclic execution paths through a piece of code. This is related to cyclomatic complexity, but the two metrics donât count the same thing: NPath counts the number of distinct full paths from the beginning to the end of the method, while Cyclo only counts the number of decision points. NPath is not computed as simply as Cyclo. With NPath, two decision points appearing sequentially have their complexity multiplied.
The fact that NPath multiplies the complexity of statements makes it grow exponentially: 10 if
- else
statements in a row would give an NPath of 1024, while Cyclo would evaluate to 20. Methods with an NPath complexity over 200 are generally considered too complex.
We compute NPath recursively, with the following set of rules:
for
, do
and while
statements is 1, plus the complexity of the block, plus the complexity of the guard condition.if
statement (if .. else if ..
) is the number of if
statements in the chain, plus the complexity of their guard condition, plus the complexity of the unguarded else
block (or 1 if there is none).switch
statement is the number of cases, plus the complexity of each case
block. Itâs equivalent to the complexity of the equivalent cascade of if
statements.?:
) is the complexity of the guard condition, plus the complexity of both expressions. Itâs equivalent to the complexity of the equivalent if .. else
construct.try .. catch
statement is the complexity of the try
block, plus the complexity of each catch block.return
statement is the complexity of the expression (or 1 if there is none).void fun(boolean a, boolean b, boolean c) { // NPath = 6
// block #0
if (a) {
// block #1
} else {
// block #2
}
// block #3
if (b) {
// block #4
} else if (c) {
// block #5
}
// block #6
}
After block 0, the control flow can either execute block 1 or 2 before jumping to block 3. From block three, the control flow will again have the choice between blocks 4 and 5 before jumping to block 6. The first if
offers 2 choices, the second offers 3, so the cyclomatic complexity of this method is 2 + 3 = 5. NPath, however, sees 2 * 3 = 6 full paths from the beginning to the end.
Class metric. Can be computed on classes.
Number Of Accessor Methods (NOAM)Class metric. Can be computed on classes.
Tight Class Cohesion (TCC)Class metric. Can be computed on classes and enums.
DescriptionThe relative number of method pairs of a class that access in common at least one attribute of the measured class. TCC only counts direct attribute accesses, that is, only those attributes that are accessed in the body of the method [BK95].
TCC is taken to be a reliable cohesion metric for a class. High values (>70%) indicate a class with one basic function, which is hard to break into subcomponents. On the other hand, low values (<50%) may indicate that the class tries to do too much and defines several unrelated services, which is undesirable.
TCC can be used to detect God Classes and Brain Classes [Lanza05].
Weighted Method Count (WMC)Class metric. Can be computed on classes and enums.
DescriptionSum of the statistical complexity of the operations in the class. We use CYCLO to quantify the complexity of an operation [Lanza05].
OptionsWMC uses the same options as CYCLO, which are provided to CYCLO when computing it.
Weight Of Class (WOC)Class metric. Can be computed on classes.
DescriptionNumber of âfunctionalâ public methods divided by the total number of public methods. Our definition of âfunctional methodâ excludes constructors, getters, and setters.
This metric tries to quantify whether the measured classâ interface reveals more data than behaviour. Low values (less than 30%) indicate that the class reveals much more data than behaviour, which is a sign of poor encapsulation.
This metric is used to detect Data Classes, in conjunction with WMC, NOPA and NOAM.
ReferencesBK95: Bieman, Kang; Cohesion and reuse in an object-oriented system. In Proceedings ACM Symposium on Software Reusability, 1995.
Lanza05: Lanza, Marinescu; Object-Oriented Metrics in Practice, 2005.
McCabe76: McCabe, A Complexity Measure, in Proceedings of the 2nd ICSE (1976).
Sonarqube: Sonarqube online documentation.
JavaNcss: JavaNCSS online documentation.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4