Rules which enforce generally accepted best practices. Instantiation by way of private constructors from outside the constructor's class often causes the generation of an accessor. A factory method, or non-privatization of the constructor can eliminate this situation. The generated class file is actually an interface. It gives the accessing class the ability to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter. This turns a private constructor effectively into one with package scope, and is challenging to discern. _Note:_ This rule is only executed for Java 10 or lower. Since Java 11, [JEP 181: Nest-Based Access Control](https://openjdk.org/jeps/181) has been implemented. This means that in Java 11 and above accessor classes are not generated anymore. 3 Declaring a MessageDigest instance as a field make this instance directly available to multiple threads. Such sharing of MessageDigest instances should be avoided if possible since it leads to wrong results if the access is not synchronized correctly. Just create a new instance and use it locally, where you need it. Creating a new instance is easier than synchronizing access to a shared instance. 3 Reassigning exception variables caught in a catch statement should be avoided because of: 1) If it is needed, multi catch can be easily added and code will still compile. 2) Following the principle of least surprise we want to make sure that a variable caught in a catch statement is always the one thrown in a try block. 3 Reassigning loop variables can lead to hard-to-find bugs. Prevent or limit how these variables can be changed. In foreach-loops, configured by the `foreachReassign` property: - `deny`: Report any reassignment of the loop variable in the loop body. _This is the default._ - `allow`: Don't check the loop variable. - `firstOnly`: Report any reassignments of the loop variable, except as the first statement in the loop body. _This is useful if some kind of normalization or clean-up of the value before using is permitted, but any other change of the variable is not._ In for-loops, configured by the `forReassign` property: - `deny`: Report any reassignment of the control variable in the loop body. _This is the default._ - `allow`: Don't check the control variable. - `skip`: Report any reassignments of the control variable, except conditional increments/decrements (`++`, `--`, `+=`, `-=`). _This prevents accidental reassignments or unconditional increments of the control variable._ 3 Reassigning values to incoming parameters of a method or constructor is not recommended, as this can make the code more difficult to understand. The code is often read with the assumption that parameter values don't change and an assignment violates therefore the principle of least astonishment. This is especially a problem if the parameter is documented e.g. in the method's javadoc and the new content differs from the original documented content. Use temporary local variables instead. This allows you to assign a new name, which makes the code better understandable. Note that this rule considers both methods and constructors. If there are multiple assignments for a formal parameter, then only the first assignment is reported. 2 StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks if held within objects with long lifetimes. 3 Application with hard-coded IP addresses can become impossible to deploy in some cases. Externalizing IP adresses is preferable. 3 Always check the return values of navigation methods (next, previous, first, last) of a ResultSet. If the value return is 'false', it should be handled properly. 3 Avoid constants in interfaces. Interfaces should define types, constants are implementation details better placed in classes or enums. See Effective Java, item 19. 3 By convention, the default label should be the last label in a switch statement. 3 Double brace initialisation is a pattern to initialise eg collections concisely. But it implicitly generates a new .class file, and the object holds a strong reference to the enclosing object. For those reasons, it is preferable to initialize the object normally, even though it's verbose. This rule counts any anonymous class which only has a single initializer as an instance of double-brace initialization. There is currently no way to find out whether a method called in the initializer is not accessible from outside the anonymous class, and those legit cases should be suppressed for the time being. 3 (){{ add("a"); add("b"); add("c"); }}; // the better way is to not create an anonymous class: List a = new ArrayList<>(); a.add("a"); a.add("b"); a.add("c"); return a; ]]> Reports loops that can be safely replaced with the foreach syntax. The rule considers loops over lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to access an element of the list or array, only has one update statement, and loops through *every* element of the list or array left to right. 3 l) { for (int i = 0; i < l.size(); i++) { // pre Java 1.5 System.out.println(l.get(i)); } for (String s : l) { // post Java 1.5 System.out.println(s); } } } ]]> Whenever using a log level, one should check if the loglevel is actually enabled, or otherwise skip the associate String creation and manipulation. An alternative to checking the log level are substituting parameters, formatters or lazy logging with lambdas. The available alternatives depend on the actual logging framework. 2 calculateExpensiveLoggingText()); ]]> In JUnit 3, test suites are indicated by the suite() method. In JUnit 4, suites are indicated through the @RunWith(Suite.class) annotation. 3 In JUnit 3, the tearDown method was used to clean up all data entities required in running tests. JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test. JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively. 3 In JUnit 3, the setUp method was used to set up all data entities required in running tests. JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests. JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively. 3 In JUnit 3, the framework executed all methods which started with the word test as a unit test. In JUnit 4, only methods annotated with the @Test annotation are executed. In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest. 3 In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions. 3 Position literals first in all String comparisons, if the second argument is null then NullPointerExceptions can be avoided, they will just return false. Note that switching literal positions for compareTo and compareToIgnoreCase may change the result, see examples. 3 0); // should be: "bar".compareTo(x) < 0 } boolean bar(String x) { return (x.compareToIgnoreCase("bar") > 0); // should be: "bar".compareToIgnoreCase(x) < 0 } boolean bar(String x) { return x.contentEquals("bar"); // should be "bar".contentEquals(x) } } ]]> The use of implementation types (i.e., HashSet) as object references limits your ability to use alternate implementations in the future as requirements change. Whenever available, referencing objects by their interface types (i.e, Set) provides much more flexibility. 3 list = new ArrayList<>(); public HashSet getFoo() { return new HashSet(); } // preferred approach private List list = new ArrayList<>(); public Set getFoo() { return new HashSet(); } } ]]> Exposing internal arrays to the caller violates object encapsulation since elements can be removed or replaced outside of the object that owns it. It is safer to return a copy of the array. 3 Annotating overridden methods with @Override ensures at compile time that the method really overrides one, which helps refactoring and clarifies intent. 3 Java allows the use of several variables declaration of the same type on one line. However, it can lead to quite messy code. This rule looks for several declarations on the same line. 4 1] [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] | //FieldDeclaration [count(VariableDeclarator) > 1] [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)] ]]> Position literals first in comparisons, if the second argument is null then NullPointerExceptions can be avoided, they will just return false. This rule is replaced by the more general rule {% rule "LiteralsFirstInComparisons" %}. 3 Position literals first in comparisons, if the second argument is null then NullPointerExceptions can be avoided, they will just return false. This rule is replaced by the more general rule {% rule "LiteralsFirstInComparisons" %}. 3 Reports usages of primitive wrapper constructors. They are deprecated since Java 9 and should not be used. Even before Java 9, they can be replaced with usage of the corresponding static `valueOf` factory method (which may be automatically inserted by the compiler since Java 1.5). This has the advantage that it may reuse common instances instead of creating a new instance each time. Note that for `Boolean`, the named constants `Boolean.TRUE` and `Boolean.FALSE` are preferred instead of `Boolean.valueOf`. 3 Consider replacing Enumeration usages with the newer java.util.Iterator 3 Consider replacing Hashtable usage with the newer java.util.Map if thread safety is not required. 3 //Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable'] Consider replacing Vector usages with the newer java.util.ArrayList if expensive thread-safe operations are not required. 3 //Type/ReferenceType/ClassOrInterfaceType[@Image='Vector'] Switch statements should be exhaustive, to make their control flow easier to follow. This can be achieved by adding a `default` case, or, if the switch is on an enum type, by ensuring there is one switch branch for each enum constant. 3 Reports assignments to variables that are never used before the variable is overwritten, or goes out of scope. Unused assignments are those for which 1. The variable is never read after the assignment, or 2. The assigned value is always overwritten by other assignments before the next read of the variable. The rule doesn't consider assignments to fields except for those of `this` in a constructor, or static fields of the current class in static initializers. The rule may be suppressed with the standard `@SuppressWarnings("unused")` tag. The rule subsumes {% rule "UnusedLocalVariable" %}, and {% rule "UnusedFormalParameter" %}. Those violations are filtered out by default, in case you already have enabled those rules, but may be enabled with the property `reportUnusedVariables`. Variables whose name starts with `ignored` or `unused` are filtered out, as is standard practice for exceptions. Limitations: * The rule currently cannot know which method calls throw exceptions, or which exceptions they throw. In the body of a try block, every method or constructor call is assumed to throw. This may cause false-negatives. The only other language construct that is assumed to throw is the `throw` statement, in particular, things like `assert` statements, or NullPointerExceptions on dereference are ignored. * The rule cannot resolve assignments across constructors, when they're called with the special `this(...)` syntax. This may cause false-negatives. Both of those limitations may be partly relaxed in PMD 7. 3 Reports parameters of methods and constructors that are not referenced them in the method body. Parameters whose name starts with `ignored` or `unused` are filtered out. Removing unused formal parameters from public methods could cause a ripple effect through the code base. Hence, by default, this rule only considers private methods. To include non-private methods, set the `checkAll` property to `true`. 3 Reports import statements that are not used within the file. This also reports duplicate imports, and imports from the same package. The simplest fix is just to delete those imports. This rule is deprecated since PMD 6.34.0. Use the rule {% rule "java/codestyle/UnnecessaryImport" %} from category codestyle instead. 4 Detects when a local variable is declared and/or assigned, but not used. Variables whose name starts with `ignored` or `unused` are filtered out. 3 Detects when a private field is declared and/or assigned a value, but not used. Since PMD 6.50.0 private fields are ignored, if the fields are annotated with any annotation or the enclosing class has any annotation. Annotations often enable a framework (such as dependency injection, mocking or e.g. Lombok) which use the fields by reflection or other means. This usage can't be detected by static code analysis. Previously these frameworks where explicitly allowed by listing their annotations in the property "ignoredAnnotations", but that turned out to be prone of false positive for any not explicitly considered framework. 3 Unused Private Method detects when a private method is declared but is unused. 3 This rule detects JUnit assertions in object references equality. These assertions should be made by more specific methods, like assertNull, assertNotNull. Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead. 3 When asserting a value is the same as a literal or Boxed boolean, use assertTrue/assertFalse, instead of assertEquals. Deprecated since PMD 6.37.0, use {% rule SimplifiableTestAssertion %} instead. 3 The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements. Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method. 3 Starting with Java 7, StandardCharsets provides constants for common Charset objects, such as UTF-8. Using the constants is less error prone, and can provide a small performance advantage compared to `Charset.forName(...)` since no scan across the internal `Charset` caches is needed. 3 `do {} while (true);` requires reading the end of the statement before it is apparent that it loops forever, whereas `while (true) {}` is easier to understand. `do {} while (false);` is redundant, and if an inner variable scope is required, a block `{}` is sufficient. `while (false) {}` will never execute the block and can be removed in its entirety. 3 = 1]] | (: while loops with conditional and'ed boolean literals, maybe parenthesized :) //WhileStatement[Expression/(AndExpression|ConditionalAndExpression|(PrimaryExpression/PrimaryPrefix/Expression/(AndExpression|ConditionalAndExpression))) (: at least one false literal :) [count(PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral[@True = false()]) >= 1]] | (: do-while loops with conditional or'ed boolean literals, maybe parenthesized :) //DoStatement[Expression/(InclusiveOrExpression|ConditionalOrExpression|(PrimaryExpression/PrimaryPrefix/Expression/(InclusiveOrExpression|ConditionalOrExpression))) [count(PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral) = 2]] | (: do-while loops with conditional and'ed boolean literals, maybe parenthesized :) //DoStatement[Expression/(AndExpression|ConditionalAndExpression|(PrimaryExpression/PrimaryPrefix/Expression/(AndExpression|ConditionalAndExpression))) (: at least one false literal :) [count(PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral[@True = false()]) >= 1 (: or two true literals (e.g. true & true) :) or count(PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral[@True = true()]) = 2]] ]]>