String and StringBuffer

These rules deal with different issues that can arise with manipulation of the String, StringBuffer, or StringBuilder instances.

AvoidDuplicateLiterals

Since: PMD 1.0

Code containing duplicate String literals can usually be improved by declaring the String as a constant field.

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

Example(s):

private void bar() {
     buz("Howdy");
     buz("Howdy");
     buz("Howdy");
     buz("Howdy");
 }
 private void buz(String x) {}

    

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.
exceptionfile File containing strings to skip (one string per line), only used if ignore list is not set
separator Ignore list separator
exceptionList Strings to ignore
maxDuplicateLiterals Max duplicate literals
minimumLength Minimum string length to check
skipAnnotations Skip literals within annotations

StringInstantiation

Since: PMD 1.0

Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared.

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

Example(s):

private String bar = new String("bar"); // just do a String bar = "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.

StringToString

Since: PMD 1.0

Avoid calling toString() on objects already known to be string instances; this is unnecessary.

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

Example(s):

private String baz() {
    String bar = "howdy";
    return bar.toString();
}

    

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.

InefficientStringBuffering

Since: PMD 3.4

Avoid concatenating non-literals in a StringBuffer constructor or append() since intermediate buffers will need to be be created and destroyed by the JVM.

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

Example(s):

    // Avoid this, two buffers are actually being created here
StringBuffer sb = new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
    
    // do this instead
StringBuffer sb = new StringBuffer("tmp = ");
sb.append(System.getProperty("java.io.tmpdir"));

    

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.

UnnecessaryCaseChange

Since: PMD 3.3

Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals()

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

Example(s):
       
boolean answer1 = buz.toUpperCase().equals("baz");	 		// should be buz.equalsIgnoreCase("baz")
    
boolean answer2 = buz.toUpperCase().equalsIgnoreCase("baz");	 // another unnecessary toUpperCase()
 
       

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.

UseStringBufferLength

Since: PMD 3.4

Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("") or StringBuffer.toString().length() == ...

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

Example(s):
  
StringBuffer sb = new StringBuffer();
    
if (sb.toString().equals("")) {}	    // inefficient 
    
if (sb.length() == 0) {}	    		// preferred
  
      

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.

AppendCharacterWithChar

Since: PMD 3.5

Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods.

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

Example(s):

StringBuffer sb = new StringBuffer();
sb.append("a");		 // avoid this

StringBuffer sb = new StringBuffer();
sb.append('a');		// use this instead

    

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.

ConsecutiveLiteralAppends

Since: PMD 3.5

Consecutively calling StringBuffer/StringBuilder.append with String literals

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

Example(s):

StringBuffer buf = new StringBuffer();
buf.append("Hello").append(" ").append("World"); // poor
buf.append("Hello World");        				 // good

    

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.
threshold Max consecutive appends

UseIndexOfChar

Since: PMD 3.5

Use String.indexOf(char) when checking for the index of a single character; it executes faster.

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

Example(s):

String s = "hello world";
  // avoid this
if (s.indexOf("d") {}
  // instead do this
if (s.indexOf('d') {}

    

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.

InefficientEmptyStringCheck

Since: PMD 3.6

String.trim().length() is an inefficient way to check if a String is really empty, as it creates a new String object just to check its size. Consider creating a static function that loops through a string, checking Character.isWhitespace() on each character and returning false if a non-whitespace character is found.

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

Example(s):

public void bar(String string) {
	if (string != null && string.trim().size() > 0) {
		doSomething();
	}
}

    

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.

InsufficientStringBufferDeclaration

Since: PMD 3.6

Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many times during runtime. This rule attempts to determine the total number the characters that are actually passed into StringBuffer.append(), but represents a best guess "worst case" scenario. An empty StringBuffer/StringBuilder constructor initializes the object to 16 characters. This default is assumed if the length of the constructor can not be determined.

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

Example(s):

StringBuffer bad = new StringBuffer();
bad.append("This is a long string that will exceed the default 16 characters");
        
StringBuffer good = new StringBuffer(41);
good.append("This is a long string, which is pre-sized");

    

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.

UselessStringValueOf

Since: PMD 3.8

No need to call String.valueOf to append to a string; just use the valueOf() argument directly.

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

Example(s):

public String convert(int i) {
	String s;
	s = "a" + String.valueOf(i);	// not required
	s = "a" + i; 					// preferred approach
	return s;
}

          

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.

StringBufferInstantiationWithChar

Since: PMD 3.9

Individual character values provided as initialization arguments will be converted into integers. This can lead to internal buffer sizes that are larger than expected. Some examples: new StringBuffer() // 16 new StringBuffer(6) // 6 new StringBuffer("hello world") // 11 + 16 = 27 new StringBuffer('A') // chr(A) = 65 new StringBuffer("A") // 1 + 16 = 17 new StringBuilder() // 16 new StringBuilder(6) // 6 new StringBuilder("hello world") // 11 + 16 = 27 new StringBuilder('C') // chr(C) = 67 new StringBuilder("A") // 1 + 16 = 17


//AllocationExpression/ClassOrInterfaceType
[@Image='StringBuffer' or @Image='StringBuilder']
/../Arguments/ArgumentList/Expression/PrimaryExpression
/PrimaryPrefix/
Literal
  [starts-with(@Image, "'")]
  [ends-with(@Image, "'")]

            
Example(s):

	// misleading instantiation, these buffers
	// are actually sized to 99 characters long
StringBuffer  sb1 = new StringBuffer('c');   
StringBuilder sb2 = new StringBuilder('c');
  
// in these forms, just single characters are allocated
StringBuffer  sb3 = new StringBuffer("c");
StringBuilder sb4 = new StringBuilder("c");

    

UseEqualsToCompareStrings

Since: PMD 4.1

Using '==' or '!=' to compare strings only works if intern version is used on both sides. Use the equals() method instead.


//EqualityExpression/PrimaryExpression
[(PrimaryPrefix/Literal
   [starts-with(@Image, '"')]
   [ends-with(@Image, '"')]
and count(PrimarySuffix) = 0)]

            
Example(s):

public boolean test(String s) {
    if (s == "one") return true; 		// unreliable
    if ("two".equals(s)) return true; 	// better
    return false;
}

    

AvoidStringBufferField

Since: PMD 4.2

StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks if held within objects with long lifetimes.


//FieldDeclaration/Type/ReferenceType/ClassOrInterfaceType[@Image = 'StringBuffer' or @Image = 'StringBuilder']

			
Example(s):

public class Foo {
	private StringBuffer buffer;	// potential memory leak as an instance variable;
}