String and StringBuffer Rules

These rules deal with different problems that can occur with manipulation of the class String or StringBuffer.

AvoidDuplicateLiterals

Since: PMD1.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):

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

    

StringInstantiation

Since: PMD1.0

Avoid instantiating String objects; this is usually unnecessary.

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

Example(s):

public class Foo {
 private String bar = new String("bar"); // just do a String bar = "bar";
}

    

StringToString

Since: PMD1.0

Avoid calling toString() on String objects; this is unnecessary.

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

Example(s):

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

    

InefficientStringBuffering

Since: PMD3.4

Avoid concatenating non literals in a StringBuffer constructor or append().

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

Example(s):

public class Foo {
 void bar() {
  // Avoid this
  StringBuffer sb=new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
  // use instead something like this
  StringBuffer sb = new StringBuffer("tmp = ");
  sb.append(System.getProperty("java.io.tmpdir"));
 }
}

    

UnnecessaryCaseChange

Since: PMD3.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):
                 
 public class Foo {
  public boolean bar(String buz) {
    // should be buz.equalsIgnoreCase("baz")
    return buz.toUpperCase().equals("baz");
    // another unnecessary toUpperCase()
    // return buz.toUpperCase().equalsIgnoreCase("baz");
  }
 }
                 
       

UseStringBufferLength

Since: PMD3.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):
  
public class Foo {
 void bar() {
  StringBuffer sb = new StringBuffer();
  // this is bad
  if(sb.toString().equals("")) {}
  // this is good
  if(sb.length() == 0) {}
 }
}

  
      

AppendCharacterWithChar

Since: PMD3.5

Avoid concatenating characters as strings in StringBuffer.append.

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

Example(s):

public class Foo {
 void bar() {
  StringBuffer sb=new StringBuffer();
  // Avoid this
  sb.append("a");

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

    

ConsecutiveLiteralAppends

Since: PMD3.5

Consecutively calling StringBuffer.append with String literals

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

Example(s):

public class Foo {
 private void bar() {
   StringBuffer buf = new StringBuffer();
   buf.append("Hello").append(" ").append("World"); //bad
   buf.append("Hello World");//good
 }
}

    

UseIndexOfChar

Since: PMD3.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):

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

    

InefficientEmptyStringCheck

Since: PMD3.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 class Foo {
    void bar(String string) {
        if (string != null && string.trim().size() > 0) {
		    doSomething();
        }
    }
}

    

InsufficientStringBufferDeclaration

Since: PMD3.6

Failing to pre-size a StringBuffer properly could cause it to re-size many times during runtime. This rule checks the characters that are actually passed into StringBuffer.append(), but represents a best guess "worst case" scenario. An empty StringBuffer 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):

public class Foo {
    void bar() {
        StringBuffer bad = new StringBuffer();
        bad.append("This is a long string, will exceed the default 16 characters");//bad
        StringBuffer good = new StringBuffer(41);
        good.append("This is a long string, which is pre-sized");//good
    }
}

    

UselessStringValueOf

Since: PMD3.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); // Bad
  s = "a" + i; // Better
  return s;
}

          

StringBufferInstantiationWithChar

Since: PMD3.9

StringBuffer sb = new StringBuffer('c'); The char will be converted into int to intialize StringBuffer size.


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

            
Example(s):

class Foo {
  StringBuffer sb1 = new StringBuffer('c'); //Bad
  StringBuffer sb2 = new StringBuffer("c"); //Better
}

    

UseEqualsToCompareStrings

Since: PMD4.1

Using '==' or '!=' to compare strings only works if intern version is used on both sides


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

            
Example(s):

class Foo {
  boolean test(String s) {
    if (s == "one") return true; //Bad
    if ("two".equals(s)) return true; //Better
    return false;
  }
}

    

AvoidStringBufferField

Since: PMD4.2

StringBuffers can grow quite a lot, and so may become a source of memory leak (if the owning class has a long life time).


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

			
Example(s):

class Foo {
	private StringBuffer memoryLeak;
}