Rules that help you discover design issues. If an abstract class does not provides any methods, it may be acting as a simple data container that is not meant to be instantiated. In this case, it is probably better to use a private or protected constructor in order to prevent instantiation than make the class misleadingly abstract. 1 Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block 3 Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain. 3 y) { if (y>z) { if (z==x) { // !! too deep } } } } } ]]> Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity. 3 Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to code size and runtime complexity. 3 *Effective Java, 3rd Edition, Item 72: Favor the use of standard exceptions* > >Arguably, every erroneous method invocation boils down to an illegal argument or state, but other exceptions are standardly used for certain kinds of illegal arguments and states. If a caller passes null in some parameter for which null values are prohibited, convention dictates that NullPointerException be thrown rather than IllegalArgumentException. To implement that, you are encouraged to use `java.util.Objects.requireNonNull()` (introduced in Java 1.7). This method is designed primarily for doing parameter validation in methods and constructors with multiple parameters. Your parameter validation could thus look like the following: ``` public class Foo { private String exampleValue; void setExampleValue(String exampleValue) { // check, throw and assignment in a single standard call this.exampleValue = Objects.requireNonNull(exampleValue, "exampleValue must not be null!"); } } ``` ]]> 1 Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead. 1 A class with only private constructors should be final, unless the private constructor is invoked by a inner class. 1 = 1 ] [count(./ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/ConstructorDeclaration[(@Public = 'true') or (@Protected = 'true') or (@PackagePrivate = 'true')]) = 0 ] [not(.//ClassOrInterfaceDeclaration)] ]]> Sometimes two consecutive 'if' statements can be consolidated by separating their conditions with a boolean short-circuit operator. 3 This rule counts the number of unique attributes, local variables, and return types within an object. A number higher than the specified threshold can indicate a high degree of coupling. 3 = 10. Additionnally, classes with many methods of moderate complexity get reported as well once the total of their methods' complexities reaches 80, even if none of the methods was directly reported. Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down into subcomponents.]]> 3 Data Classes are simple data holders, which reveal most of their state, and without complex functionality. The lack of functionality may indicate that their behaviour is defined elsewhere, which is a sign of poor data-behaviour proximity. By directly exposing their internals, Data Classes break encapsulation, and therefore reduce the system's maintainability and understandability. Moreover, classes tend to strongly rely on their data representation, which makes for a brittle design. Refactoring a Data Class should focus on restoring a good data-behaviour proximity. In most cases, that means moving the operations defined on the data back into the class. In some other cases it may make sense to remove entirely the class and move the data into the former client classes. 3 Errors are system exceptions. Do not extend them. 3 Using Exceptions as form of flow control is not recommended as they obscure true exceptions when debugging. Either add the necessary validation or use an alternate control structure. 3 Excessive class file lengths are usually indications that the class may be burdened with excessive responsibilities that could be provided by external classes or functions. In breaking these methods apart the code becomes more manageable and ripe for reuse. 3 A high number of imports can indicate a high degree of coupling within an object. This rule counts the number of unique imports and reports a violation if the count is above the user-specified threshold. 3 When methods are excessively long this usually indicates that the method is doing more than its name/signature might suggest. They also become challenging for others to digest since excessive scrolling causes readers to lose focus. Try to reduce the method length by creating helper methods and removing any copy/pasted code. 3 Methods with numerous parameters are a challenge to maintain, especially if most of them share the same datatype. These situations usually denote the need for new objects to wrap the numerous parameters. 3 Classes with large numbers of public methods and attributes require disproportionate testing efforts since combinational side effects grow rapidly and increase risk. Refactoring these classes into smaller ones not only increases testability and reliability but also allows new variations to be developed easily. 3 If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead in each object at runtime. 3 The God Class rule detects the God Class design flaw using metrics. God classes do too many things, are very big and overly complex. They should be split apart to be more object-oriented. The rule uses the detection strategy described in "Object-Oriented Metrics in Practice". The violations are reported against the entire class. See also the references: Michele Lanza and Radu Marinescu. Object-Oriented Metrics in Practice: Using Software Metrics to Characterize, Evaluate, and Improve the Design of Object-Oriented Systems. Springer, Berlin, 1 edition, October 2006. Page 80. 3 Identifies private fields whose values never change once object initialization ends either in the declaration of the field or by a constructor. This helps in converting existing classes to becoming immutable ones. 3 The Law of Demeter is a simple rule, that says "only talk to friends". It helps to reduce coupling between classes or objects. See also the references: * Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.; * K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.; * <http://www.ccs.neu.edu/home/lieber/LoD.html> * <http://en.wikipedia.org/wiki/Law_of_Demeter> 3 Use opposite operator instead of negating the whole expression with a logic complement operator. 3 = return false; } return true; } ]]> Avoid using classes from the configured package hierarchy outside of the package hierarchy, except when using one of the configured allowed classes. 3 Complexity directly affects maintenance costs is determined by the number of decision points in a method plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls. Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote high complexity, and 11+ is very high complexity. Modified complexity treats switch statements as a single decision point. This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced by the rule {% rule java/design/CyclomaticComplexity %}. 3 This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one. This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced by the rule {% rule java/design/NcssCount %}. 3 This rule uses the NCSS (Non-Commenting Source Statements) metric to determine the number of lines of code in a class, method or constructor. NCSS ignores comments, blank lines, and only counts actual statements. For more details on the calculation, see the documentation of the [NCSS metric](/pmd_java_metrics_index.html#non-commenting-source-statements-ncss). 3 This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one. This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced by the rule {% rule java/design/NcssCount %}. 3 This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm, lines of code that are split are counted as one. This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced by the rule {% rule java/design/NcssCount %}. 3 The NPath complexity of a method is the number of acyclic execution paths through that method. While cyclomatic complexity counts the number of decision points in a method, NPath counts the number of full paths from the beginning to the end of the block of the method. That metric grows exponentially, as it multiplies the complexity of statements in the same block. For more details on the calculation, see the documentation of the [NPath metric](/pmd_java_metrics_index.html#npath-complexity-npath). A threshold of 200 is generally considered the point where measures should be taken to reduce complexity and increase readability. 3 A method/constructor shouldn't explicitly throw the generic java.lang.Exception, since it is unclear which exceptions that can be thrown from the methods. It might be difficult to document and understand such vague interfaces. Use either a class derived from RuntimeException or a checked exception. 3 3 Avoid negation in an assertTrue or assertFalse test. For example, rephrase: assertTrue(!expr); as: assertFalse(expr); 3 Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability. 3 Avoid unnecessary if-then-else statements when returning a boolean. The result of the conditional test can be returned instead. 3 No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument. 3 Fields whose scopes are limited to just single methods do not rely on the containing object to provide them to other methods. They may be better implemented as local variables within those methods. 3 Complexity directly affects maintenance costs is determined by the number of decision points in a method plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls. Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote high complexity, and 11+ is very high complexity. This rule is deprecated and will be removed with PMD 7.0.0. The rule is replaced by the rule {% rule java/design/CyclomaticComplexity %}. 3 A high ratio of statements to labels in a switch statement implies that the switch statement is overloaded. Consider moving the statements into new methods or creating subclasses based on the switch variable. 3 Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields, possibly through grouping related fields in new objects. For example, a class with individual city/state/zip fields could park them within a single Address field. 3 A class with too many methods is probably a good suspect for refactoring, in order to reduce its complexity and find a way to have more fine grained objects. 3 $maxmethods ] ]]> The overriding method merely calls the same method defined in a superclass. 3 When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information as a simple series of Strings, you may think of using an Object to represent all those information. You'll get a simpler API (such as doWork(Workload workload), rather than a tedious series of Strings) and more importantly, if you need at some point to pass extra data, you'll be able to do so by simply modifying or extending Workload without any modification to your API. 3 3 ] ]]> For classes that only have static methods, consider making them utility classes. Note that this doesn't apply to abstract classes, since their subclasses may well include non-static methods. Also, if you want this class to be a utility class, remember to add a private constructor to prevent instantiation. (Note, that this use was known before PMD 5.1.0 as UseSingleton). 3