##### Overview

- Download PMD 5.0.4
- What's new in PMD 5.0.4
- PMD in the news
- PMD-related products and books
- Best practices
- Future directions
- Similar projects
- Credits
- License
- What does 'PMD' mean?

##### Usage

- Installation
- Command line usage
- Ant task usage
- Maven plugin usage
- Mvn plugin usage
- IDE plugin usage
- Suppressing warnings
- Finding duplicated code
- JSP support

##### Customizing PMD

- Compiling PMD
- How to write a rule
- Writing XPath rules
- How to make a rule set
- How it works
- Rule guidelines
- PMD developers information
- PMD Release Process

##### For example

- Run PMD on a Sourceforge project

##### Misc.

- XPath tutorial (Gregorian)

##### Rule Sets

- ecmascript
  - Basic Ecmascript
  - Braces
  - Unnecessary
- java
  - Android
  - Basic
  - Braces
  - Clone Implementation
  - Code Size
  - Comments
  - Controversial
  - Coupling
  - Design
  - Empty Code
  - Finalizer
  - Import Statements
  - J2EE
  - JavaBeans
  - JUnit
  - Jakarta Commons Logging
  - Java Logging
  - Migration
  - Naming
  - Optimization
  - Strict Exceptions
  - String and StringBuffer
  - Security Code Guidelines
  - Type Resolution
  - Unnecessary
  - Unused Code
- jsp
  - Basic JSF
  - Basic JSP
- xml
  - Basic XML
- xsl
  - XPath in XSL

##### Project Documentation

- Project Information
- Project Reports

## Optimization

These rules deal with different optimizations that generally apply to best practices.

### LocalVariableCouldBeFinal

Since: PMD 2.2

A local variable assigned only once can be declared final.

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

Example(s):

    public class Bar {
    	public void foo () {
    		String txtA = "a"; 		// if txtA will not be assigned again it is better to do this:
    		final String txtB = "b";
    	}
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### MethodArgumentCouldBeFinal

Since: PMD 2.2

A method argument that is never re-assigned within the method can be declared final.

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

Example(s):

    public void foo1 (String param) {	// do stuff with param never assigning it

    }

    public void foo2 (final String param) {	// better, do stuff with param never assigning it

    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### AvoidInstantiatingObjectsInLoops

Since: PMD 2.2

New objects created within loops should be checked to see if they can created outside them and reused.

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

Example(s):

    public class Something {
    	public static void main( String as[] ) {
    		for (int i = 0; i < 10; i++) {
    		    Foo f = new Foo(); // Avoid this whenever you can it's really expensive
    		}
    	}
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### UseArrayListInsteadOfVector

Since: PMD 3.0

ArrayList is a much better Collection implementation than Vector if thread-safe operation is not required.

    //AllocationExpression
     /ClassOrInterfaceType[@Image='Vector' or @Image='java.util.Vector']

Example(s):

    public class SimpleTest extends TestCase {
    	public void testX() {
    		Collection c1 = new Vector();
    		Collection c2 = new ArrayList();	// achieves the same with much better performance
    	}
    }

### SimplifyStartsWith

Since: PMD 3.1

Since it passes in a literal of length 1, calls to (string).startsWith can be rewritten using (string).charAt(0) at the expense of some readability.

    //PrimaryExpression
     [PrimaryPrefix/Name
      [ends-with(@Image, '.startsWith')]]
     [PrimarySuffix/Arguments/ArgumentList
      /Expression/PrimaryExpression/PrimaryPrefix
      /Literal
       [string-length(@Image)=3]
       [starts-with(@Image, '"')]
       [ends-with(@Image, '"')]
     ]

Example(s):

    public class Foo {

    	boolean checkIt(String x) {
    		return x.startsWith("a");	// suboptimal
    	}

    	boolean fasterCheckIt(String x) {
    		return x.charAt(0) == 'a';	//	faster approach
    	}
    }

### UseStringBufferForStringAppends

Since: PMD 3.1

The use of the '+=' operator for appending strings causes the JVM to create and use an internal StringBuffer. If a non-trivial number of these concatenations are being used then the explicit use of a StringBuilder or threadsafe StringBuffer is recommended to avoid this.

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

Example(s):

    public class Foo {
      void bar() {
        String a;
        a = "foo";
        a += " bar";
       // better would be:
       // StringBuilder a = new StringBuilder("foo");
       // a.append(" bar);
      }
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### UseArraysAsList

Since: PMD 3.5

The java.util.Arrays class has a "asList" method that should be used when you want to create a new List from an array of objects. It is faster than executing a loop to copy all the elements of the array one by one.

    //Statement[
        (ForStatement) and (count(.//IfStatement)=0)
       ]
       //StatementExpression[
        PrimaryExpression/PrimaryPrefix/Name[
         substring-before(@Image,'.add') = ancestor::MethodDeclaration//LocalVariableDeclaration[
          ./Type//ClassOrInterfaceType[
           @Image = 'Collection' or
           @Image = 'List' or @Image='ArrayList'
          ]
         ]
         /VariableDeclarator/VariableDeclaratorId[
          count(..//AllocationExpression/ClassOrInterfaceType[
           @Image="ArrayList"
          ]
          )=1
         ]/@Image
        ]
       and
       PrimaryExpression/PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
       [
         @Image = ancestor::MethodDeclaration//LocalVariableDeclaration[@Array="true"]/VariableDeclarator/VariableDeclaratorId/@Image
         or
         @Image = ancestor::MethodDeclaration//FormalParameter/VariableDeclaratorId/@Image
       ]
       /../..[count(.//PrimarySuffix)
       =1]/PrimarySuffix/Expression/PrimaryExpression/PrimaryPrefix
       /Name
       ]

Example(s):

    public class Test {
      public void foo(Integer[] ints) {
        // could just use Arrays.asList(ints)
         List l= new ArrayList(10);
         for (int i=0; i< 100; i++) {
           l.add(ints[i]);
         }
         for (int i=0; i< 100; i++) {
           l.add(a[i].toString()); // won't trigger the rule
         }
      }
    }

### AvoidArrayLoops

Since: PMD 3.5

Instead of manually copying data between two arrays, use the efficient System.arraycopy method instead.

    //Statement[(ForStatement or WhileStatement) and
    count(*//AssignmentOperator[@Image = '='])=1
    and
    */Statement
    [
    ./Block/BlockStatement/Statement/StatementExpression/PrimaryExpression
    /PrimaryPrefix/Name/../../PrimarySuffix/Expression
    [(PrimaryExpression or AdditiveExpression) and count
    (.//PrimaryPrefix/Name)=1]//PrimaryPrefix/Name/@Image
    and
    ./Block/BlockStatement/Statement/StatementExpression/Expression/PrimaryExpression
    /PrimaryPrefix/Name/../../PrimarySuffix[count
    (..//PrimarySuffix)=1]/Expression[(PrimaryExpression
    or AdditiveExpression) and count(.//PrimaryPrefix/Name)=1]
    //PrimaryPrefix/Name/@Image
    ]]

Example(s):

    public class Test {
      public void bar() {
        int[] a = new int[10];
        int[] b = new int[10];
        for (int i=0;i<10;i++) {
          b[i]=a[i];
        }
      }
    }
         // this will trigger the rule
         for (int i=0;i<10;i++) {
           b[i]=a[c[i]];
         }

      }
    }

### UnnecessaryWrapperObjectCreation

Since: PMD 3.8

Most wrapper classes provide static conversion methods that avoid the need to create intermediate objects just to create the primitive forms. Using these avoids the cost of creating objects that also need to be garbage-collected later.

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

Example(s):

    public int convert(String s) {
      int i, i2;

      i = Integer.valueOf(s).intValue(); // this wastes an object
      i = Integer.parseInt(s); 			 // this is better

      i2 = Integer.valueOf(i).intValue(); // this wastes an object
      i2 = i; // this is better

      String s3 = Integer.valueOf(i2).toString(); // this wastes an object
      s3 = Integer.toString(i2); 		// this is better

      return i2;
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### AddEmptyString

Since: PMD 4.0

The conversion of literals to strings by concatenating them with empty strings is inefficient. It is much better to use one of the type-specific toString() methods instead.

    //AdditiveExpression/PrimaryExpression/PrimaryPrefix/Literal[@Image='""']

Example(s):

    String s = "" + 123; 				// inefficient
    String t = Integer.toString(456); 	// preferred approach

### RedundantFieldInitializer

Since: PMD 5.0

Java will initialize fields with known default values so any explicit initialization of those same defaults is redundant and results in a larger class file (approximately three additional bytecode instructions per field).

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

Example(s):

    public class C {
    	boolean b	= false;	// examples of redundant initializers
    	byte by		= 0;
    	short s		= 0;
    	char c		= 0;
    	int i		= 0;
    	long l		= 0;

    	float f		= .0f;    // all possible float literals
    	doable d	= 0d;     // all possible double literals
    	Object o	= null;

    	MyClass mca[] = null;
    	int i1 = 0, ia1[] = null;

    	class Nested {
    		boolean b = false;
    	}
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.

### PrematureDeclaration

Since: PMD 5.0

Checks for variables that are defined before they might be used. A reference is deemed to be premature if it is created right before a block of code that doesn't use it that also has the ability to return or throw an exception.

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

Example(s):

    public int getLength(String[] strings) {

      int length = 0;	// declared prematurely

      if (strings == null || strings.length == 0) return 0;

      for (String str : strings) {
        length += str.length();
        }

      return length;
    }

This rule has the following properties:

Name | Default Value | Description
violationSuppressRegex |  | Suppress violations with messages matching a regular expression
violationSuppressXPath |  | Suppress violations on nodes which match a given relative XPath expression.