Rules that help you discover design issues.

AbstractClassWithoutAnyMethod

Since: PMD 4.2

Priority: High (1)

If an abstract class does not provide 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.

This rule is defined by the following XPath expression:

//ClassOrInterfaceDeclaration
    [@Abstract = true() and @Interface = false()]
    [ClassOrInterfaceBody[not(ConstructorDeclaration | MethodDeclaration)]]
    [not(pmd-java:hasAnnotation('com.google.auto.value.AutoValue')
         or pmd-java:hasAnnotation('lombok.AllArgsConstructor')
         or pmd-java:hasAnnotation('lombok.NoArgsConstructor')
         or pmd-java:hasAnnotation('lombok.RequiredArgsConstructor'))
    ]

Example(s):

public abstract class Example {
    String field;
    int otherField;
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AbstractClassWithoutAnyMethod" />

AvoidCatchingGenericException

Since: PMD 4.2.6

Priority: Medium (3)

Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block.

This rule is defined by the following XPath expression:

//CatchParameter//ClassOrInterfaceType[
    pmd-java:typeIsExactly('java.lang.NullPointerException') or
    pmd-java:typeIsExactly('java.lang.Exception') or
    pmd-java:typeIsExactly('java.lang.RuntimeException')]

Example(s):

package com.igate.primitive;

public class PrimitiveType {

    public void downCastPrimitiveType() {
        try {
            System.out.println(" i [" + i + "]");
        } catch(Exception e) {
            e.printStackTrace();
        } catch(RuntimeException e) {
            e.printStackTrace();
        } catch(NullPointerException e) {
            e.printStackTrace();
        }
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidCatchingGenericException" />

AvoidDeeplyNestedIfStmts

Since: PMD 1.0

Priority: Medium (3)

Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.AvoidDeeplyNestedIfStmtsRule

Example(s):

public class Foo {
  public void bar(int x, int y, int z) {
    if (x>y) {
      if (y>z) {
        if (z==x) {
         // !! too deep
        }
      }
    }
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
problemDepth 3 The if statement depth reporting threshold no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/AvoidDeeplyNestedIfStmts" />

Use this rule and customize it:

<rule ref="category/java/design.xml/AvoidDeeplyNestedIfStmts">
    <properties>
        <property name="problemDepth" value="3" />
    </properties>
</rule>

AvoidRethrowingException

Since: PMD 3.8

Priority: Medium (3)

Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.

This rule is defined by the following XPath expression:

//CatchClause[
  CatchParameter/VariableDeclaratorId/@Name
= Block[@Size = 1]/ThrowStatement/VariableAccess/@Name]

Example(s):

public void bar() {
    try {
        // do something
    }  catch (SomeException se) {
       throw se;
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidRethrowingException" />

AvoidThrowingNewInstanceOfSameException

Since: PMD 4.2.5

Priority: Medium (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.

This rule is defined by the following XPath expression:

//CatchClause
    [count(Block/*) = 1]
    [CatchParameter/ClassOrInterfaceType/@SimpleName = Block/ThrowStatement/ConstructorCall/ClassOrInterfaceType/@SimpleName]
    [Block/ThrowStatement/ConstructorCall/ArgumentList/@Size = 1]
    /Block/ThrowStatement/ConstructorCall

Example(s):

public void bar() {
    try {
        // do something
    } catch (SomeException se) {
        // harmless comment
        throw new SomeException(se);
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidThrowingNewInstanceOfSameException" />

AvoidThrowingNullPointerException

Since: PMD 1.8

Priority: High (1)

Avoid throwing NullPointerExceptions manually. These are confusing because most people will assume that the virtual machine threw it. To avoid a method being called with a null parameter, you may consider using an IllegalArgumentException instead, making it clearly seen as a programmer-initiated exception. However, there are better ways to handle this:

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!");
    }
  }

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.AvoidThrowingNullPointerExceptionRule

Example(s):

public class Foo {
    void bar() {
        throw new NullPointerException();
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidThrowingNullPointerException" />

AvoidThrowingRawExceptionTypes

Since: PMD 1.8

Priority: High (1)

Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable, Exception, or Error, use a subclassed exception or error instead.

This rule is defined by the following XPath expression:

//ThrowStatement//ConstructorCall
 /ClassOrInterfaceType[
 pmd-java:typeIsExactly('java.lang.Throwable')
or
 pmd-java:typeIsExactly('java.lang.Exception')
or
 pmd-java:typeIsExactly('java.lang.Error')
or
 pmd-java:typeIsExactly('java.lang.RuntimeException')
]

Example(s):

public class Foo {
    public void bar() throws Exception {
        throw new Exception();
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidThrowingRawExceptionTypes" />

AvoidUncheckedExceptionsInSignatures

Since: PMD 6.13.0

Priority: Medium (3)

Reports unchecked exceptions in the throws clause of a method or constructor. Java doesn’t force the caller to handle an unchecked exception, so it’s unnecessary except for documentation. A better practice is to document the exceptional cases with a @throws Javadoc tag, which allows being more descriptive.

This rule is defined by the following XPath expression:

//ThrowsList/ClassOrInterfaceType[pmd-java:typeIs('java.lang.RuntimeException')]

Example(s):

public void foo() throws RuntimeException {
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/AvoidUncheckedExceptionsInSignatures" />

ClassWithOnlyPrivateConstructorsShouldBeFinal

Since: PMD 4.1

Priority: High (1)

Reports classes that may be made final because they cannot be extended from outside their compilation unit anyway. This is because all their constructors are private, so a subclass could not call the super constructor.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ClassWithOnlyPrivateConstructorsShouldBeFinalRule

Example(s):

public class Foo {  //Should be final
    private Foo() { }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal" />

CognitiveComplexity

Since: PMD 6.35.0

Priority: Medium (3)

Methods that are highly complex are difficult to read and more costly to maintain. If you include too much decisional logic within a single method, you make its behavior hard to understand and more difficult to modify.

Cognitive 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: https://www.sonarsource.com/docs/CognitiveComplexity.pdf

By default, this rule reports methods with a complexity of 15 or more. Reported methods should be broken down into less complex components.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.CognitiveComplexityRule

Example(s):

public class Foo {
  // Has a cognitive complexity of 0
  public void createAccount() {
    Account account = new Account("PMD");
    // save account
  }

  // Has a cognitive complexity of 1
  public Boolean setPhoneNumberIfNotExisting(Account a, String phone) {
    if (a.phone == null) {                          // +1
      a.phone = phone;
      return true;
    }

    return false;
  }

  // Has a cognitive complexity of 4
  public void updateContacts(List<Contact> contacts) {
    List<Contact> contactsToUpdate = new ArrayList<Contact>();

    for (Contact contact : contacts) {                           // +1
      if (contact.department.equals("Finance")) {                // +2 (nesting = 1)
        contact.title = "Finance Specialist";
        contactsToUpdate.add(contact);
      } else if (contact.department.equals("Sales")) {           // +1
        contact.title = "Sales Specialist";
        contactsToUpdate.add(contact);
      }
    }
    // save contacts
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
reportLevel 15 Cognitive Complexity reporting threshold no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/CognitiveComplexity" />

Use this rule and customize it:

<rule ref="category/java/design.xml/CognitiveComplexity">
    <properties>
        <property name="reportLevel" value="15" />
    </properties>
</rule>

CollapsibleIfStatements

Since: PMD 3.1

Priority: Medium (3)

Reports nested ‘if’ statements that can be merged together by joining their conditions with a boolean && operator in between.

This rule is defined by the following XPath expression:

//IfStatement[@Else = false()]/IfStatement[@Else = false()]
|
//IfStatement[@Else = false()]/Block[count(*) = 1]/IfStatement[@Else = false()]

Example(s):

class Foo {

    void bar() {
        if (x) {            // original implementation
            if (y) {
                // do stuff
            }
        }
    }

    void bar() {
        if (x && y) {        // clearer implementation
            // do stuff
        }
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/CollapsibleIfStatements" />

CouplingBetweenObjects

Since: PMD 1.04

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.CouplingBetweenObjectsRule

Example(s):

import com.Blah;
import org.Bar;
import org.Bardo;

public class Foo {
    private Blah var1;
    private Bar var2;

    //followed by many imports of unique objects
    ObjectC doWork() {
        Bardo var55;
        ObjectA var44;
        ObjectZ var93;
        return something();
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
threshold 20 Unique type reporting threshold no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/CouplingBetweenObjects" />

Use this rule and customize it:

<rule ref="category/java/design.xml/CouplingBetweenObjects">
    <properties>
        <property name="threshold" value="20" />
    </properties>
</rule>

CyclomaticComplexity

Since: PMD 1.03

Priority: Medium (3)

The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic in a single method makes its behaviour hard to read and change.

Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method, plus one for the method entry. Decision points are places where the control flow jumps to another place in the program. As such, they include all control flow statements, such as if, while, for, and case. For more details on the calculation, see the documentation CYCLO.

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. By default, this rule reports methods with a complexity >= 10. Additionally, 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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.CyclomaticComplexityRule

Example(s):

class Foo {
  void baseCyclo() {                // Cyclo = 1
    highCyclo();
  }

  void highCyclo() {                // Cyclo = 10: reported!
    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;
      }
    }
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
classReportLevel 80 Total class complexity reporting threshold no
methodReportLevel 10 Cyclomatic complexity reporting threshold no
cycloOptions   Choose options for the computation of Cyclo yes. Delimiter is ‘|’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/CyclomaticComplexity" />

Use this rule and customize it:

<rule ref="category/java/design.xml/CyclomaticComplexity">
    <properties>
        <property name="classReportLevel" value="80" />
        <property name="methodReportLevel" value="10" />
        <property name="cycloOptions" value="" />
    </properties>
</rule>

DataClass

Since: PMD 6.0.0

Priority: Medium (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.

The rule uses metrics to implement its detection strategy. The violation message gives information about the values of these metrics:

The rule identifies a god class by looking for classes which have all of the following properties:

  • High NOPA + NOAM
  • Low WOC
  • Low WMC

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.DataClassRule

Example(s):

public class DataClass {

  // class exposes public attributes
  public String name = "";
  public int bar = 0;
  public int na = 0;

  private int bee = 0;

  // and private ones through getters
  public void setBee(int n) {
    bee = n;
  }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/DataClass" />

DoNotExtendJavaLangError

Since: PMD 4.0

Priority: Medium (3)

Errors are system exceptions. Do not extend them.

This rule is defined by the following XPath expression:

//ClassOrInterfaceDeclaration/ExtendsList/ClassOrInterfaceType[pmd-java:typeIs('java.lang.Error')]

Example(s):

public class Foo extends Error { }

Use this rule by referencing it:

<rule ref="category/java/design.xml/DoNotExtendJavaLangError" />

ExceptionAsFlowControl

Since: PMD 1.8

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExceptionAsFlowControlRule

Example(s):

public void bar() {
    try {
        try {
        } catch (Exception e) {
            throw new WrapperException(e);
            // this is essentially a GOTO to the WrapperException catch block
        }
    } catch (WrapperException e) {
        // do some more stuff
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/ExceptionAsFlowControl" />

ExcessiveClassLength

Deprecated

Since: PMD 0.6

Priority: Medium (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.

Note: This rule is deprecated since PMD 6.53.0 and will be removed with PMD 7.0.0.

The rule is based on the simple metric lines of code (LoC). The reasons for deprecation are:

  • LoC is a noisy metric, NCSS (non-commenting source statements) is a more solid metric (results are code-style independent, comment-insensitive)
  • LoC is easily circumvented by bad code style (e.g. stuffing several assignments into one, concatenating code lines)
  • Enforcing length limits with LoC is not very meaningful, could even be called a bad practice

In order to find "big" classes, the rule NcssCount can be used instead.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExcessiveClassLengthRule

Example(s):

public class Foo {
    public void bar1() {
        // 1000 lines of code
    }
    public void bar2() {
        // 1000 lines of code
    }
    public void bar3() {
        // 1000 lines of code
    }

    public void barN() {
        // 1000 lines of code
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 1000 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ExcessiveClassLength" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ExcessiveClassLength">
    <properties>
        <property name="minimum" value="1000" />
    </properties>
</rule>

ExcessiveImports

Since: PMD 1.04

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExcessiveImportsRule

Example(s):

import blah.blah.Baz;
import blah.blah.Bif;
// 28 others from the same package elided
public class Foo {
    public void doWork() {}
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 30 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ExcessiveImports" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ExcessiveImports">
    <properties>
        <property name="minimum" value="30" />
    </properties>
</rule>

ExcessiveMethodLength

Deprecated

Since: PMD 0.6

Priority: Medium (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.

Note: This rule is deprecated since PMD 6.53.0 and will be removed with PMD 7.0.0.

The rule is based on the simple metric lines of code (LoC). The reasons for deprecation are:

  • LoC is a noisy metric, NCSS (non-commenting source statements) is a more solid metric (results are code-style independent, comment-insensitive)
  • LoC is easily circumvented by bad code style (e.g. stuffing several assignments into one, concatenating code lines)
  • Enforcing length limits with LoC is not very meaningful, could even be called a bad practice

In order to find "big" methods, the rule NcssCount can be used instead.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExcessiveMethodLengthRule

Example(s):

public void doSomething() {
    System.out.println("Hello world!");
    System.out.println("Hello world!");
    // 98 copies omitted for brevity.
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 100 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ExcessiveMethodLength" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ExcessiveMethodLength">
    <properties>
        <property name="minimum" value="100" />
    </properties>
</rule>

ExcessiveParameterList

Since: PMD 0.9

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExcessiveParameterListRule

Example(s):

public void addPerson(      // too many arguments liable to be mixed up
    int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {

    . . . .
}

public void addPerson(      // preferred approach
    Date birthdate, BodyMeasurements measurements, int ssn) {

    . . . .
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 10 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ExcessiveParameterList" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ExcessiveParameterList">
    <properties>
        <property name="minimum" value="10" />
    </properties>
</rule>

ExcessivePublicCount

Since: PMD 1.04

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ExcessivePublicCountRule

Example(s):

public class Foo {
    public String value;
    public Bar something;
    public Variable var;
    // [... more more public attributes ...]

    public void doWork() {}
    public void doMoreWork() {}
    public void doWorkAgain() {}
    // [... more more public methods ...]
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 45 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ExcessivePublicCount" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ExcessivePublicCount">
    <properties>
        <property name="minimum" value="45" />
    </properties>
</rule>

FinalFieldCouldBeStatic

Since: PMD 1.1

Priority: Medium (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.

This rule is defined by the following XPath expression:

//FieldDeclaration
    [pmd-java:modifiers() = 'final']
    [not(pmd-java:modifiers() = 'static')]
    [not(.//Annotation[pmd-java:typeIs('lombok.Builder.Default')])]
    /VariableDeclarator[*[pmd-java:nodeIs('Literal')]
         or VariableAccess[@Name = //FieldDeclaration[pmd-java:modifiers() = 'static']/VariableDeclarator/VariableDeclaratorId/@Name]
         or FieldAccess
         or ArrayAllocation/ArrayType/ArrayDimensions/ArrayDimExpr/NumericLiteral[@IntLiteral = true()][@Image = "0"]]
    /VariableDeclaratorId
        [not(@Name = //MethodDeclaration[not(pmd-java:modifiers() = 'static')]
            //SynchronizedStatement/(VariableAccess|FieldAccess[ThisExpression])/@Name)]

Example(s):

public class Foo {
  public final int BAR = 42; // this could be static and save some space
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/FinalFieldCouldBeStatic" />

GodClass

Since: PMD 5.0

Priority: Medium (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.

The rule uses metrics to implement its detection strategy. The violation message gives information about the values of these metrics:

The rule identifies a god class by looking for classes which have all of the following properties:

  • High WMC
  • High ATFD
  • Low TCC

See also the reference:

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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.GodClassRule

Use this rule by referencing it:

<rule ref="category/java/design.xml/GodClass" />

ImmutableField

Since: PMD 2.0

Priority: Medium (3)

Reports non-final fields whose value never changes once object initialization ends, and hence may be marked final.

Note that this rule does not enforce that the field value be deeply immutable itself. An object can still have mutable state, even if all its member fields are declared final. This is referred to as shallow immutability. For more information on mutability, see Effective Java, 3rd Edition, Item 17: Minimize mutability.

Limitations: We can only check private fields for now.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.ImmutableFieldRule

Example(s):

public class Foo {
  private int x; // could be final
  public Foo() {
      x = 7;
  }
  public void foo() {
     int a = x + 2;
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
ignoredAnnotations   Fully qualified names of the annotation types that should be ignored by this rule yes. Delimiter is ‘|’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/ImmutableField" />

Use this rule and customize it:

<rule ref="category/java/design.xml/ImmutableField">
    <properties>
        <property name="ignoredAnnotations" value="" />
    </properties>
</rule>

InvalidJavaBean

Since: PMD 6.52.0

Priority: Medium (3)

Identifies beans, that don’t follow the JavaBeans API specification.

Each non-static field should have both a getter and a setter method. If the field is just used internally and is not a bean property, then the field should be marked as transient.

The rule verifies that the type of the field is the same as the result type of the getter. And that this type matches the type used in the setter.

The rule also checks, that there is a no-arg or default constructor available.

Optionally the rule also verifies, that the bean implements java.io.Serializable. While this is a requirement for the original JavaBeans specification, frameworks nowadays don’t strictly require this anymore.

In order to avoid many false positives in classes that are not beans, the rule needs to be explicitly enabled by configuring the property packages.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.InvalidJavaBeanRule

Example(s):

package org.example.beans;
public class MyBean {        // <-- bean is not serializable, missing "implements Serializable"
    private String label;    // <-- missing setter for property "label"

    public String getLabel() {
        return label;
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
ensureSerialization false Require that beans implement java.io.Serializable. no
packages org.example.beans Consider classes in only these package to be beans. Set to an empty value to check all classes. yes. Delimiter is ‘,’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/InvalidJavaBean" />

Use this rule and customize it:

<rule ref="category/java/design.xml/InvalidJavaBean">
    <properties>
        <property name="ensureSerialization" value="false" />
        <property name="packages" value="org.example.beans" />
    </properties>
</rule>

LawOfDemeter

Since: PMD 5.0

Priority: Medium (3)

The law of Demeter is a simple rule that says "only talk to friends". It forbids fetching data from "too far away", for some definition of distance, in order to reduce coupling between classes or objects of different levels of abstraction.

The rule uses a notion of "degree", that quantifies how "far" an object is. Expressions with too high degree can only be used in certain ways. The degree of an expression is defined inductively:

  • The degree of this is 0
  • The degree of a method parameter is 1
  • The degree of a new object created in a method is 1
  • The degree of a static variable is 1
  • The degree of a field access expression like expr.field is the degree of expr plus 1
  • The degree of a "getter expression" like expr.getFoo() is the degree of expr plus 1
  • The degree of a "transformation expression" like expr.withFoo("") is the degree of expr
  • The degree of a variable is the maximum degree of all the assignments that reach it

Intuitively, the more you call getters, the more the degree increases. Eventually the degree reaches the report threshold (property trustRadius) and the expression is reported. The details of the calculation are more involved and make room for common patterns, like usage of collections (objects that are in a list or array have the same degree as their container), the builder pattern, and getters that do not appear to break a boundary of abstraction.

Be aware that this rule is prone to many false-positives and low-priority warnings. You can increase the trustRadius property to reduce them drastically. The default trustRadius of 1 corresponds to the original law of Demeter (you’re only allowed one getter call on untrusted values). Given some trustRadius value:

  • expressions of degree lower or equal to trustRadius are not reported
  • expressions of degree exactly trustRadius + 1 are reported, unless they are only returned from the current method, or passed as argument to another method. Without this exception it would not be possible to extract any information from e.g. method parameters.
  • values of degree strictly greater than trustRadius + 1 are not reported. The intuition is that to obtain a value of degree n > 1 then you must use an expression of degree n - 1, so if you have n > trustRadius + 1, there you’re using some value of degree trustRadius + 1 that will be reported.

See also the references:

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.LawOfDemeterRule

Example(s):

public class Foo {
    /**
     * This example will result in one violation.
     */
    public void example(Bar b) { // b has degree 1
        // `b.getC()` has degree 2, it's breaking a boundary of abstraction and so is reported.
        b.getC().doIt();
        // To respect the law of Demeter, Bar should encapsulate its
        // C member more properly, eg by exposing a method like this:
        b.callDoItOnC();

        // a constructor call, not a method call.
        D d = new D();
        // this method call is ok, because we have create the new
        // instance of D locally.
        d.doSomethingElse();
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
trustRadius 1 Maximum degree of trusted data. The default of 1 is the most restrictive. no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/LawOfDemeter" />

Use this rule and customize it:

<rule ref="category/java/design.xml/LawOfDemeter">
    <properties>
        <property name="trustRadius" value="1" />
    </properties>
</rule>

LogicInversion

Since: PMD 5.0

Priority: Medium (3)

Use opposite operator instead of negating the whole expression with a logic complement operator.

This rule is defined by the following XPath expression:

//UnaryExpression[@Operator='!']/InfixExpression[@Operator = ('==', '!=', '<', '>', '<=', '>=')]

Example(s):

public boolean bar(int a, int b) {

    if (!(a == b)) { // use !=
         return false;
     }

    if (!(a < b)) { // use >=
         return false;
    }

    return true;
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/LogicInversion" />

LoosePackageCoupling

Since: PMD 5.0

Priority: Medium (3)

Avoid using classes from the configured package hierarchy outside of the package hierarchy, except when using one of the configured allowed classes.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.LoosePackageCouplingRule

Example(s):

package some.package;

import some.other.package.subpackage.subsubpackage.DontUseThisClass;

public class Bar {
    DontUseThisClass boo = new DontUseThisClass();
}

This rule has the following properties:

Name Default Value Description Multivalued
packages   Restricted packages yes. Delimiter is ‘,’.
classes   Allowed classes yes. Delimiter is ‘,’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/LoosePackageCoupling" />

Use this rule and customize it:

<rule ref="category/java/design.xml/LoosePackageCoupling">
    <properties>
        <property name="packages" value="" />
        <property name="classes" value="" />
    </properties>
</rule>

MutableStaticState

Since: PMD 6.35.0

Priority: Medium (3)

Non-private static fields should be made constants (or immutable references) by declaring them final.

Non-private non-final static fields break encapsulation and can lead to hard to find bugs, since these fields can be modified from anywhere within the program. Callers can trivially access and modify non-private non-final static fields. Neither accesses nor modifications can be guarded against, and newly set values cannot be validated.

If you are using this rule, then you don’t need this rule AssignmentToNonFinalStatic.

This rule is defined by the following XPath expression:

//FieldDeclaration[pmd-java:modifiers() = "static"][not(pmd-java:modifiers() = ("private", "final"))]

Example(s):

public class Greeter { public static Foo foo = new Foo(); ... }       // avoid this
public class Greeter { public static final Foo FOO = new Foo(); ... } // use this instead

Use this rule by referencing it:

<rule ref="category/java/design.xml/MutableStaticState" />

NcssCount

Since: PMD 6.0.0

Priority: Medium (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 NCSS.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.NcssCountRule

Example(s):

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
    }
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
methodReportLevel 60 NCSS reporting threshold for methods no
classReportLevel 1500 NCSS reporting threshold for classes no
ncssOptions   Choose options for the computation of Ncss yes. Delimiter is ‘|’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/NcssCount" />

Use this rule and customize it:

<rule ref="category/java/design.xml/NcssCount">
    <properties>
        <property name="methodReportLevel" value="60" />
        <property name="classReportLevel" value="1500" />
        <property name="ncssOptions" value="" />
    </properties>
</rule>

NPathComplexity

Since: PMD 3.9

Priority: Medium (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 NPATH.

A threshold of 200 is generally considered the point where measures should be taken to reduce complexity and increase readability.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.NPathComplexityRule

Example(s):

public class Foo {
  public static void bar() { // Ncss = 252: reported!
    boolean a, b = true;
    try { // 2 * 2 + 2 = 6
      if (true) { // 2
        List buz = new ArrayList();
      }

      for(int i = 0; i < 19; i++) { // * 2
        List buz = new ArrayList();
      }
    } catch(Exception e) {
      if (true) { // 2
        e.printStackTrace();
      }
    }

    while (j++ < 20) { //  * 2
      List buz = new ArrayList();
    }

    switch(j) { // * 7
      case 1:
      case 2: break;
      case 3: j = 5; break;
      case 4: if (b && a) { bar(); } break;
      default: break;
    }

    do { // * 3
        List buz = new ArrayList();
    } while (a && j++ < 30);
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
reportLevel 200 N-Path Complexity reporting threshold no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/NPathComplexity" />

Use this rule and customize it:

<rule ref="category/java/design.xml/NPathComplexity">
    <properties>
        <property name="reportLevel" value="200" />
    </properties>
</rule>

SignatureDeclareThrowsException

Since: PMD 1.2

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.SignatureDeclareThrowsExceptionRule

Example(s):

public void foo() throws Exception {
}

This rule has the following properties:

Name Default Value Description Multivalued
IgnoreJUnitCompletely false Allow all methods in a JUnit3 TestCase to throw Exceptions no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/SignatureDeclareThrowsException" />

Use this rule and customize it:

<rule ref="category/java/design.xml/SignatureDeclareThrowsException">
    <properties>
        <property name="IgnoreJUnitCompletely" value="false" />
    </properties>
</rule>

SimplifiedTernary

Since: PMD 5.4.0

Priority: Medium (3)

Reports ternary expression with the form condition ? literalBoolean : foo or condition ? foo : literalBoolean.

These expressions can be simplified as follows:

  • condition ? true : expr simplifies to condition || expr
  • condition ? false : expr simplifies to !condition && expr
  • condition ? expr : true simplifies to !condition || expr
  • condition ? expr : false simplifies to condition && expr

This rule is defined by the following XPath expression:

//ConditionalExpression[BooleanLiteral and not(NullLiteral)]

Example(s):

public class Foo {
    public boolean test() {
        return condition ? true : something(); // can be as simple as return condition || something();
    }

    public void test2() {
        final boolean value = condition ? false : something(); // can be as simple as value = !condition && something();
    }

    public boolean test3() {
        return condition ? something() : true; // can be as simple as return !condition || something();
    }

    public void test4() {
        final boolean otherValue = condition ? something() : false; // can be as simple as condition && something();
    }

    public boolean test5() {
        return condition ? true : false; // can be as simple as return condition;
    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/SimplifiedTernary" />

SimplifyBooleanExpressions

Since: PMD 1.05

Priority: Medium (3)

Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator = ("==", "!=")]/BooleanLiteral

Example(s):

public class Bar {
  // can be simplified to
  // bar = isFoo();
  private boolean bar = (isFoo() == true);

  public isFoo() { return false;}
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/SimplifyBooleanExpressions" />

SimplifyBooleanReturns

Since: PMD 0.9

Priority: Medium (3)

Avoid unnecessary if-then-else statements when returning a boolean. The result of the conditional test can be returned instead.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.SimplifyBooleanReturnsRule

Example(s):

public boolean isBarEqualTo(int x) {
    if (bar == x) {      // this bit of code...
        return true;
    } else {
        return false;
    }
}

public boolean isBarEqualTo(int x) {
    return bar == x;    // can be replaced with this
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/SimplifyBooleanReturns" />

SimplifyConditional

Since: PMD 3.1

Priority: Medium (3)

No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.SimplifyConditionalRule

Example(s):

class Foo {
  void bar(Object x) {
    if (x != null && x instanceof Bar) {
      // just drop the "x != null" check
    }
  }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/SimplifyConditional" />

SingularField

Since: PMD 3.1

Priority: Medium (3)

Reports fields which may be converted to a local variable. This is so because in every method where the field is used, it is assigned before it is first read. Hence, the value that the field had before the method call may not be observed, so it might as well not be stored in the enclosing object.

Limitations: We can only check private fields for now.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.SingularFieldRule

Example(s):

public class Foo {
    private int x; // this will be reported

    public void foo(int y) {
       x = y + 5; // assigned before any read
       return x;
    }

    public void fooOk(int y) {
       int z = y + 5; // might as well be a local like here
       return z;
    }
}

This rule has the following properties:

Name Default Value Description Multivalued
ignoredAnnotations java.lang.Deprecated | javafx.fxml.FXML | lombok.Getter | lombok.Setter | lombok.experimental.Delegate Fully qualified names of the annotation types that should be ignored by this rule yes. Delimiter is ‘|’.

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/SingularField" />

Use this rule and customize it:

<rule ref="category/java/design.xml/SingularField">
    <properties>
        <property name="ignoredAnnotations" value="java.lang.Deprecated|javafx.fxml.FXML|lombok.Getter|lombok.Setter|lombok.experimental.Delegate" />
    </properties>
</rule>

SwitchDensity

Since: PMD 1.02

Priority: Medium (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.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.SwitchDensityRule

Example(s):

public class Foo {
  public void bar(int x) {
    switch (x) {
      case 1: {
        // lots of statements
        break;
      } case 2: {
        // lots of statements
        break;
      }
    }
  }
}

This rule has the following properties:

Name Default Value Description Multivalued
minimum 10.0 Threshold above which a node is reported no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/SwitchDensity" />

Use this rule and customize it:

<rule ref="category/java/design.xml/SwitchDensity">
    <properties>
        <property name="minimum" value="10.0" />
    </properties>
</rule>

TooManyFields

Since: PMD 3.0

Priority: Medium (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.

This rule is defined by the following XPath expression:

//ClassOrInterfaceDeclaration/ClassOrInterfaceBody
  [count(FieldDeclaration
            [not(pmd-java:modifiers() = 'final')]
            [not(pmd-java:modifiers() = 'static')]
        ) > $maxfields]

Example(s):

public class Person {   // too many separate fields
   int birthYear;
   int birthMonth;
   int birthDate;
   float height;
   float weight;
}

public class Person {   // this is more manageable
   Date birthDate;
   BodyMeasurements measurements;
}

This rule has the following properties:

Name Default Value Description Multivalued
maxfields 15 Max allowable fields no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/TooManyFields" />

Use this rule and customize it:

<rule ref="category/java/design.xml/TooManyFields">
    <properties>
        <property name="maxfields" value="15" />
    </properties>
</rule>

TooManyMethods

Since: PMD 4.2

Priority: Medium (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.

This rule is defined by the following XPath expression:

//ClassOrInterfaceDeclaration/ClassOrInterfaceBody
     [
      count(MethodDeclaration[
         not (
                (starts-with(@Name,'get') or starts-with(@Name,'set') or starts-with(@Name,'is'))
                and
                count(Block/*) <= 1
            )
      ]) > $maxmethods
   ]

This rule has the following properties:

Name Default Value Description Multivalued
maxmethods 10 The method count reporting threshold no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/TooManyMethods" />

Use this rule and customize it:

<rule ref="category/java/design.xml/TooManyMethods">
    <properties>
        <property name="maxmethods" value="10" />
    </properties>
</rule>

UselessOverridingMethod

Since: PMD 3.3

Priority: Medium (3)

The overriding method merely calls the same method defined in a superclass.

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.UselessOverridingMethodRule

Example(s):

public void foo(String bar) {
    super.foo(bar);      // why bother overriding?
}

public String foo() {
    return super.foo();  // why bother overriding?
}

@Id
public Long getId() {
    return super.getId();  // OK if 'ignoreAnnotations' is false, which is the default behavior
}

This rule has the following properties:

Name Default Value Description Multivalued
ignoreAnnotations false Ignore methods that have annotations (except @Override) no

Use this rule with the default properties by just referencing it:

<rule ref="category/java/design.xml/UselessOverridingMethod" />

Use this rule and customize it:

<rule ref="category/java/design.xml/UselessOverridingMethod">
    <properties>
        <property name="ignoreAnnotations" value="false" />
    </properties>
</rule>

UseObjectForClearerAPI

Since: PMD 4.2.6

Priority: Medium (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.

This rule is defined by the following XPath expression:

//MethodDeclaration[pmd-java:modifiers() = 'public']
    [count(FormalParameters/FormalParameter[pmd-java:typeIs('java.lang.String')]) > 3]

Example(s):

public class MyClass {
    public void connect(String username,
        String pssd,
        String databaseName,
        String databaseAdress)
        // Instead of those parameters object
        // would ensure a cleaner API and permit
        // to add extra data transparently (no code change):
        // void connect(UserData data);
    {

    }
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/UseObjectForClearerAPI" />

UseUtilityClass

Since: PMD 0.3

Priority: Medium (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).

This rule is defined by the following Java class: net.sourceforge.pmd.lang.java.rule.design.UseUtilityClassRule

Example(s):

public class MaybeAUtility {
  public static void foo() {}
  public static void bar() {}
}

Use this rule by referencing it:

<rule ref="category/java/design.xml/UseUtilityClass" />