These rules deal with different optimizations that generally apply to performance best practices.
A local variable assigned only once can be declared final.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.LocalVariableCouldBeFinal
Here's an example of code that would trigger this rule:
public class Bar {
public void foo () {
String a = "a"; //if a will not be assigned again it is better to do this:
final String b = "b";
}
}
A method argument that is never assigned can be declared final.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.MethodArgumentCouldBeFinal
Here's an example of code that would trigger this rule:
public void foo (String param) {
// do stuff with param never assigning it
// better: public void foo (final String param) {
}
Detects when a new object is created inside a loop
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.AvoidInstantiatingObjectsInLoops
Here's an example of code that would trigger this rule:
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
}
}
}
ArrayList is a much better Collection implementation than Vector.
This rule is defined by the following XPath expression:
//AllocationExpression
/ClassOrInterfaceType[@Image='Vector' or @Image='java.util.Vector']
Here's an example of code that would trigger this rule:
public class SimpleTest extends TestCase {
public void testX() {
Collection c = new Vector();
// This achieves the same with much better performance
// Collection c = new ArrayList();
}
}
Since it passes in a literal of length 1, this call to String.startsWith can be rewritten using String.charAt(0) to save some time.
This rule is defined by the following XPath expression:
//PrimaryExpression
[PrimaryPrefix/Name
[ends-with(@Image, '.startsWith')]]
[PrimarySuffix/Arguments/ArgumentList
/Expression/PrimaryExpression/PrimaryPrefix
/Literal
[string-length(@Image)=3]
[starts-with(@Image, '"')]
[ends-with(@Image, '"')]
]
Here's an example of code that would trigger this rule:
public class Foo {
boolean checkIt(String x) {
return x.startsWith("a");
}
}
Finds usages of += for appending strings.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.UseStringBufferForStringAppends
Here's an example of code that would trigger this rule:
public class Foo {
void bar() {
String a;
a = "foo";
a += " bar";
// better would be:
// StringBuffer a = new StringBuffer("foo");
// a.append(" bar);
}
}
The class java.util.Arrays has a "asList" method that should be use when you want to create a new List from an array of objects. It is faster than executing a loop to cpy all the elements of the array one by one
This rule is defined by the following XPath expression:
//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]
/../..[count(.//PrimarySuffix)
=1]/PrimarySuffix/Expression/PrimaryExpression/PrimaryPrefix
/Name
]
Here's an example of code that would trigger this rule:
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
}
}
}
Instead of copying data between two arrays, use System.arrayCopy method
This rule is defined by the following XPath expression:
//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
]]
Here's an example of code that would trigger this rule:
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]];
}
}
}
Parsing method should be called directy instead.
This rule is defined by the following Java class: net.sourceforge.pmd.rules.optimization.UnnecessaryWrapperObjectCreation
Here's an example of code that would trigger this rule:
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
return i2;
}