Movatterモバイル変換


[0]ホーム

URL:


 
» Performance Edit on GitHub

Performance

Rules that flag suboptimal code.
Table of Contents

AddEmptyString

Since: PMD 4.0

Priority: Medium (3)

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

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

Example(s):

Strings=""+123;// inefficientStringt=Integer.toString(456);// preferred approach

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AddEmptyString"/>

AppendCharacterWithChar

Since: PMD 3.5

Priority: Medium (3)

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.performance.AppendCharacterWithCharRule

Example(s):

StringBuffersb=newStringBuffer();sb.append("a");// avoid thisStringBuffersb=newStringBuffer();sb.append('a');// use this instead

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AppendCharacterWithChar"/>

AvoidArrayLoops

Since: PMD 3.5

Priority: Medium (3)

Instead of manually copying data between two arrays, use the more efficientArrays.copyOforSystem.arraycopy method instead.

To copy only part of the array, useArrays.copyOfRange orSystem.arraycopy.

If you want to copy/move elements inside thesame array (e.g. shift the elements), useSystem.arraycopy.

This rule is defined by the following XPath expression:

//(ForStatement[ForUpdate//(UnaryExpression[@Operator=('++','--')]|AssignmentExpression[@Operator=('+=','-=')][NumericLiteral[@Image='1']])]|WhileStatement|DoStatement)[not(.//ContinueStatement)][not(.//BreakStatement)][not(.//ThrowStatement)][not(.//ReturnStatement)][count(Block//AssignmentExpression[@Operator='='](: no nested arrays or method calls as array index :)[count(ArrayAccess[not(.//ArrayAccess)][not(.//MethodCall)])=2](: array access indexes must be same (excluding constants) :)[deep-equal(sort(distinct-values(ArrayAccess[1]/(VariableAccess[2]|InfixExpression//VariableAccess)(: don't consider array length accesses :)[not(parent::FieldAccess[@Name='length'])][(: exclude referenced constants :)not(@Name=(ancestor::MethodDeclaration|//FieldDeclaration)//VariableDeclarator[NumericLiteral][not(../../../parent::ForInit)]/VariableId/@Name)or(: include loop variable :)@Name=ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]/@Name)),sort(distinct-values(ArrayAccess[2]/(VariableAccess[2]|InfixExpression//VariableAccess)(: don't consider array length accesses :)[not(parent::FieldAccess[@Name='length'])][(: exclude referenced constants :)not(@Name=(ancestor::MethodDeclaration|//FieldDeclaration)//VariableDeclarator[NumericLiteral][not(../../../parent::ForInit)]/VariableId/@Name)or(: include loop variable :)@Name=ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]/@Name)))])=1]

Example(s):

classScratch{voidcopy_a_to_b(){int[]a=newint[10];int[]b=newint[10];for(inti=0;i<a.length;i++){b[i]=a[i];}// equivalentb=Arrays.copyOf(a,a.length);// equivalentSystem.arraycopy(a,0,b,0,a.length);int[]c=newint[10];// this will not trigger the rulefor(inti=0;i<c.length;i++){b[i]=a[c[i]];}}}
classScratch{voidshift_left(int[]a){for(inti=0;i<a.length-1;i++){a[i]=a[i+1];}// equivalentSystem.arraycopy(a,1,a,0,a.length-1);}voidshift_right(int[]a){for(inti=a.length-1;i>0;i--){a[i]=a[i-1];}// equivalentSystem.arraycopy(a,0,a,1,a.length-1);}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AvoidArrayLoops"/>

AvoidCalendarDateCreation

Since: PMD 6.25.0

Priority: Medium (3)

Problem:java.util.Calendar is a heavyweight object and expensive to create. It should only be used, ifcalendar calculations are needed.

Solution: Usenew Date(), Java 8+java.time.LocalDateTime.now() orZonedDateTime.now().

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.util.Calendar#getTime()")orpmd-java:matchesSig("java.util.Calendar#getTimeInMillis()")][*[1][local-name()=('MethodCall','ConstructorCall')][pmd-java:matchesSig("java.util.Calendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#new()")]]|//MethodCall[pmd-java:matchesSig("java.util.Calendar#getTime()")orpmd-java:matchesSig("java.util.Calendar#getTimeInMillis()")][*[1][local-name()='VariableAccess']](: ignore if .set* or .add or .clear or .roll is called on the variable :)[not(VariableAccess/@Name=ancestor::Block//MethodCall[starts-with(@MethodName,"set")or@MethodName=("add","clear","roll")]/VariableAccess/@Name)](: variable must be initialized with getInstance :)[VariableAccess/@Name=ancestor::Block//LocalVariableDeclaration/VariableDeclarator[(MethodCall|ConstructorCall)[pmd-java:matchesSig("java.util.Calendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#new()")]]/VariableId/@Name]|//ConstructorCall[pmd-java:typeIs("org.joda.time.DateTime")orpmd-java:typeIs("org.joda.time.LocalDateTime")][ArgumentList[(MethodCall|ConstructorCall)[pmd-java:matchesSig("java.util.Calendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")orpmd-java:matchesSig("java.util.GregorianCalendar#new()")]]]

Example(s):

importjava.time.LocalDateTime;importjava.util.Calendar;importjava.util.Date;publicclassDateStuff{privateDatebad1(){returnCalendar.getInstance().getTime();// now}privateDategood1a(){returnnewDate();// now}privateLocalDateTimegood1b(){returnLocalDateTime.now();}privatelongbad2(){returnCalendar.getInstance().getTimeInMillis();}privatelonggood2(){returnSystem.currentTimeMillis();}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AvoidCalendarDateCreation"/>

AvoidFileStream

Since: PMD 6.0.0

Priority: High (1)

Minimum Language Version: Java 1.7

The FileInputStream and FileOutputStream classes contains a finalizer method which will cause garbagecollection pauses.SeeJDK-8080225 for details.

The FileReader and FileWriter constructors instantiate FileInputStream and FileOutputStream,again causing garbage collection issues while finalizer methods are called.

  • UseFiles.newInputStream(Paths.get(fileName)) instead ofnew FileInputStream(fileName).
  • UseFiles.newOutputStream(Paths.get(fileName)) instead ofnew FileOutputStream(fileName).
  • UseFiles.newBufferedReader(Paths.get(fileName)) instead ofnew FileReader(fileName).
  • UseFiles.newBufferedWriter(Paths.get(fileName)) instead ofnew FileWriter(fileName).

Please note, that thejava.nio API does not throw aFileNotFoundException anymore, insteadit throws aNoSuchFileException. If your code dealt explicitly with aFileNotFoundException,then this needs to be adjusted. Both exceptions are subclasses ofIOException, so catchingthat one covers both.

This rule is defined by the following XPath expression:

//ConstructorCall/ClassType[pmd-java:typeIs('java.io.FileInputStream')orpmd-java:typeIs('java.io.FileOutputStream')orpmd-java:typeIs('java.io.FileReader')orpmd-java:typeIs('java.io.FileWriter')]

Example(s):

// these instantiations cause garbage collection pauses, even if properly closedFileInputStreamfis=newFileInputStream(fileName);FileOutputStreamfos=newFileOutputStream(fileName);FileReaderfr=newFileReader(fileName);FileWriterfw=newFileWriter(fileName);// the following instantiations help prevent Garbage Collection pauses, no finalizationtry(InputStreamis=Files.newInputStream(Paths.get(fileName))){}try(OutputStreamos=Files.newOutputStream(Paths.get(fileName))){}try(BufferedReaderbr=Files.newBufferedReader(Paths.get(fileName),StandardCharsets.UTF_8)){}try(BufferedWriterwr=Files.newBufferedWriter(Paths.get(fileName),StandardCharsets.UTF_8)){}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AvoidFileStream"/>

AvoidInstantiatingObjectsInLoops

Since: PMD 2.2

Priority: Medium (3)

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.performance.AvoidInstantiatingObjectsInLoopsRule

Example(s):

publicclassSomething{publicstaticvoidmain(Stringas[]){for(inti=0;i<10;i++){Foof=newFoo();// Avoid this whenever you can it's really expensive}}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops"/>

BigIntegerInstantiation

Since: PMD 3.9

Priority: Medium (3)

Don’t create instances of already existing BigInteger (BigInteger.ZERO,BigInteger.ONE),for Java 1.5 onwards, BigInteger.TEN and BigDecimal (BigDecimal.ZERO,BigDecimal.ONE,BigDecimal.TEN) andfor Java 9 onwardsBigInteger.TWO.

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

Example(s):

BigIntegerbi1=newBigInteger("1");// reference BigInteger.ONE insteadBigIntegerbi2=newBigInteger("0");// reference BigInteger.ZERO insteadBigIntegerbi3;bi3=newBigInteger("0");// reference BigInteger.ZERO insteadBigDecimalbd1=newBigDecimal(0);// reference BigDecimal.ZERO insteadBigDecimalbd2=newBigDecimal("0.");// reference BigDecimal.ZERO insteadBigDecimalbd3=newBigDecimal(10);// reference BigDecimal.TEN instead

Use this rule by referencing it:

<ruleref="category/java/performance.xml/BigIntegerInstantiation"/>

ConsecutiveAppendsShouldReuse

Since: PMD 5.1

Priority: Medium (3)

Consecutive calls to StringBuffer/StringBuilder .append should be chained, reusing the target object. This can improve the performanceby producing a smaller bytecode, reducing overhead and improving inlining. A complete analysis can be foundhere

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

Example(s):

Stringfoo=" ";StringBufferbuf=newStringBuffer();buf.append("Hello");// poorbuf.append(foo);buf.append("World");StringBufferbuf=newStringBuffer();buf.append("Hello").append(foo).append("World");// good

Use this rule by referencing it:

<ruleref="category/java/performance.xml/ConsecutiveAppendsShouldReuse"/>

ConsecutiveLiteralAppends

Since: PMD 3.5

Priority: Medium (3)

Consecutively calling StringBuffer/StringBuilder.append(…) with literals should be avoided.Since the literals are constants, they can already be combined into a single String literal and this Stringcan be appended in a single method call.

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

Example(s):

StringBuilderbuf=newStringBuilder();buf.append("Hello").append(" ").append("World");// poorbuf.append("Hello World");// goodbuf.append('h').append('e').append('l').append('l').append('o');// poorbuf.append("hello");// goodbuf.append(1).append('m');// poorbuf.append("1m");// good

This rule has the following properties:

NameDefault ValueDescription
threshold1Max consecutive appends

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

<ruleref="category/java/performance.xml/ConsecutiveLiteralAppends"/>

Use this rule and customize it:

<ruleref="category/java/performance.xml/ConsecutiveLiteralAppends"><properties><propertyname="threshold"value="1"/></properties></rule>

InefficientEmptyStringCheck

Since: PMD 3.6

Priority: Medium (3)

String.trim().length() == 0 (or String.trim().isEmpty() for the same reason) is an inefficientway to check if a String is really blank, 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. A Smarter code tocheck for an empty string would be:

privatebooleancheckTrimEmpty(Stringstr){for(inti=0;i<str.length();i++){if(!Character.isWhitespace(str.charAt(i))){returnfalse;}}returntrue;}

You can refer to Apache’s StringUtils#isBlank (in commons-lang),Spring’s StringUtils#hasText (in the Spring framework) or Google’sCharMatcher#whitespace (in Guava) for existing implementations (some mightinclude the check for != null).

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

Example(s):

publicvoidbar(Stringstring){if(string!=null&&string.trim().length()>0){doSomething();}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/InefficientEmptyStringCheck"/>

InefficientStringBuffering

Since: PMD 3.4

Priority: Medium (3)

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

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

Example(s):

// Avoid this, two buffers are actually being created hereStringBuffersb=newStringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));// do this insteadStringBuffersb=newStringBuffer("tmp = ");sb.append(System.getProperty("java.io.tmpdir"));

Use this rule by referencing it:

<ruleref="category/java/performance.xml/InefficientStringBuffering"/>

InsufficientStringBufferDeclaration

Since: PMD 3.6

Priority: Medium (3)

Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many timesduring runtime. This rule attempts to determine the total number the characters that are actuallypassed into StringBuffer.append(), but represents a best guess "worst case" scenario. An emptyStringBuffer/StringBuilder constructor initializes the object to 16 characters. This defaultis 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.performance.InsufficientStringBufferDeclarationRule

Example(s):

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

Use this rule by referencing it:

<ruleref="category/java/performance.xml/InsufficientStringBufferDeclaration"/>

OptimizableToArrayCall

Since: PMD 1.8

Priority: Medium (3)

Minimum Language Version: Java 1.6

Calls to a collection’stoArray(E[]) method should specify a target array of zero size. This allows the JVMto optimize the memory allocation and copying as much as possible.

Previous versions of this rule (pre PMD 6.0.0) suggested the opposite, but current JVM implementationsperform always better, when they have full control over the target array. And allocation an array viareflection is nowadays as fast as the direct allocation.

See alsoArrays of Wisdom of the Ancients

Note: If you don’t need an array of the correct type, then the simpletoArray() method without an arrayis faster, but returns only an array of typeObject[].

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.util.Collection#toArray(_)")][ArgumentList/ArrayAllocation/ArrayType/ArrayDimensions/ArrayDimExpr[not(NumericLiteral[@Image="0"])]]

Example(s):

List<Foo>foos=getFoos();// much better; this one allows the jvm to allocate an array of the correct size and effectively skip// the zeroing, since each array element will be overridden anywaysFoo[]fooArray=foos.toArray(newFoo[0]);// inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray methodFoo[]fooArray=foos.toArray(newFoo[foos.size()]);

Use this rule by referencing it:

<ruleref="category/java/performance.xml/OptimizableToArrayCall"/>

RedundantFieldInitializer

Since: PMD 5.0

Priority: Medium (3)

Java will initialize fields with known default values so any explicit initialization of those same defaultsis 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.performance.RedundantFieldInitializerRule

Example(s):

publicclassC{booleanb=false;// examples of redundant initializersbyteby=0;shorts=0;charc=0;inti=0;longl=0;floatf=.0f;// all possible float literalsdoubled=0d;// all possible double literalsObjecto=null;MyClassmca[]=null;inti1=0,ia1[]=null;classNested{booleanb=false;}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/RedundantFieldInitializer"/>

StringInstantiation

Since: PMD 1.0

Priority: Medium High (2)

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.performance.StringInstantiationRule

Example(s):

privateStringbar=newString("bar");// just do a String bar = "bar";

Use this rule by referencing it:

<ruleref="category/java/performance.xml/StringInstantiation"/>

StringToString

Since: PMD 1.0

Priority: Medium (3)

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

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.String#toString()")]

Example(s):

privateStringbaz(){Stringbar="howdy";returnbar.toString();}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/StringToString"/>

TooFewBranchesForASwitchStatement

Deprecated

This rule has been renamed. Use instead:TooFewBranchesForSwitch

Deprecated

Since: PMD 4.2

Priority: Medium (3)

Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a fewcases is ill-advised, since switches are not as easy to understand as if-else statements. In these cases use theif-else statement to increase code readability.

Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0.

This rule is defined by the following XPath expression:

//(SwitchStatement|SwitchExpression)[count(*)>1](: ignore empty switch blocks :)[(count(*/SwitchLabel/*)+count(*/SwitchLabel[@Default=true()]))<$minimumNumberCaseForASwitch](: do not consider exhaustive switches unless there is a default case :)[@Exhaustive=false()or@DefaultCase=true()]

Example(s):

// With a minimumNumberCaseForASwitch of 3publicclassFoo{publicvoidbar(intcondition){switch(condition){case1:instruction;break;default:break;// not enough for a 'switch' stmt, a simple 'if' stmt would have been more appropriate}}}

This rule has the following properties:

NameDefault ValueDescription
minimumNumberCaseForASwitch3Minimum number of branches for a switch

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

<ruleref="category/java/performance.xml/TooFewBranchesForASwitchStatement"/>

Use this rule and customize it:

<ruleref="category/java/performance.xml/TooFewBranchesForASwitchStatement"><properties><propertyname="minimumNumberCaseForASwitch"value="3"/></properties></rule>

TooFewBranchesForSwitch

Since: PMD 4.2

Priority: Medium (3)

Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a fewcases is ill-advised, since switches are not as easy to understand as if-else statements. In these cases use theif-else statement to increase code readability.

Note: This rule was named TooFewBranchesForASwitchStatement before PMD 7.7.0.

This rule is defined by the following XPath expression:

//(SwitchStatement|SwitchExpression)[count(*)>1](: ignore empty switch blocks :)[(count(*/SwitchLabel/*)+count(*/SwitchLabel[@Default=true()]))<$minimumNumberCaseForASwitch](: do not consider exhaustive switches unless there is a default case :)[@Exhaustive=false()or@DefaultCase=true()]

Example(s):

// With a minimumNumberCaseForASwitch of 3publicclassFoo{publicvoidbar(intcondition){switch(condition){case1:instruction;break;default:break;// not enough for a 'switch' stmt, a simple 'if' stmt would have been more appropriate}}}

This rule has the following properties:

NameDefault ValueDescription
minimumNumberCaseForASwitch3Minimum number of branches for a switch

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

<ruleref="category/java/performance.xml/TooFewBranchesForSwitch"/>

Use this rule and customize it:

<ruleref="category/java/performance.xml/TooFewBranchesForSwitch"><properties><propertyname="minimumNumberCaseForASwitch"value="3"/></properties></rule>

UseArrayListInsteadOfVector

Since: PMD 3.0

Priority: Medium (3)

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

This rule is defined by the following XPath expression:

//ConstructorCall/ClassType[pmd-java:typeIsExactly('java.util.Vector')orpmd-java:typeIsExactly('Vector')]

Example(s):

importjava.util.*;publicclassSimpleTestextendsTestCase{publicvoidtestX(){Collectionc1=newVector();Collectionc2=newArrayList();// achieves the same with much better performance}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseArrayListInsteadOfVector"/>

UseArraysAsList

Since: PMD 3.5

Priority: Medium (3)

Thejava.util.Arrays class has aasList() method that should be used when you want to create a new List froman array of objects. It is faster than executing a loop to copy all the elements of the array one by one.

Note that the result ofArrays.asList() is backed by the specified array,changes in the returned list will result in the array to be modified.For that reason, it is not possible to add new elements to the returned list ofArrays.asList()(UnsupportedOperationException).You must usenew ArrayList<>(Arrays.asList(...)) if that is inconvenient for you (e.g. because of concurrent access).

This rule is defined by the following XPath expression:

//ForStatement[ForInit[LocalVariableDeclaration[PrimitiveType[@Kind='int']][VariableDeclarator[NumericLiteral[@IntLiteral][@Image='0']]]]][*[2]//FieldAccess[@Name='length']/VariableAccess[pmd-java:typeIs("java.lang.Object[]")]]/*[last()]/ExpressionStatement/MethodCall[pmd-java:matchesSig('java.util.List#add(_)')][ArgumentList/ArrayAccess[VariableAccess[@Name=ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]]]|//ForeachStatement[VariableAccess[pmd-java:typeIs("java.lang.Object[]")]]/*[last()]/ExpressionStatement/MethodCall[pmd-java:matchesSig('java.util.List#add(_)')][ArgumentList[VariableAccess[@Name=ancestor::ForeachStatement/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]]]

Example(s):

publicclassTest{publicvoidfoo(Integer[]ints){// could just use Arrays.asList(ints)List<Integer>l=newArrayList<>(100);for(inti=0;i<ints.length;i++){l.add(ints[i]);}List<Integer>anotherList=newArrayList<>();for(inti=0;i<ints.length;i++){anotherList.add(ints[i].toString());// won't trigger the rule}}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseArraysAsList"/>

UseIndexOfChar

Since: PMD 3.5

Priority: Medium (3)

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.performance.UseIndexOfCharRule

Example(s):

Strings="hello world";// avoid thisif(s.indexOf("d"){}// instead do thisif(s.indexOf('d'){}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseIndexOfChar"/>

UseIOStreamsWithApacheCommonsFileItem

Since: PMD 6.25.0

Priority: Medium (3)

Problem: Use ofFileItem.get()andFileItem.getString()could exhaust memory since they load the entire file into memory.

Solution: UseFileItem.getInputStream()and buffering.

This rule is defined by the following XPath expression:

//MethodCall[@MethodName='get'or@MethodName='getString'][*[pmd-java:typeIs('org.apache.commons.fileupload.FileItem')]]

Example(s):

importorg.apache.commons.fileupload.FileItem;publicclassFileStuff{privateStringbad(FileItemfileItem){returnfileItem.getString();}privateInputStreamgood(FileItemfileItem){returnfileItem.getInputStream();}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseIOStreamsWithApacheCommonsFileItem"/>

UselessStringValueOf

Since: PMD 3.8

Priority: Medium (3)

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.performance.UselessStringValueOfRule

Example(s):

publicStringconvert(inti){Strings;s="a"+String.valueOf(i);// not requireds="a"+i;// preferred approachreturns;}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UselessStringValueOf"/>

UseStringBufferForStringAppends

Since: PMD 3.1

Priority: Medium (3)

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 orthreadsafe StringBuffer is recommended to avoid this.

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

Example(s):

publicclassFoo{StringinefficientConcatenation(){Stringresult="";for(inti=0;i<10;i++){// warning: this concatenation will create one new StringBuilder per iterationresult+=getStringFromSomeWhere(i);}returnresult;}StringefficientConcatenation(){// better would be to use one StringBuilder for the entire loopStringBuilderresult=newStringBuilder();for(inti=0;i<10;i++){result.append(getStringFromSomeWhere(i));}returnresult.toString();}}

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseStringBufferForStringAppends"/>

UseStringBufferLength

Since: PMD 3.4

Priority: Medium (3)

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

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig('_#length()')andMethodCall[pmd-java:matchesSig('java.lang.CharSequence#toString()')]]|(: finds sb.toString().equals(someVar) where var is a final variable initialized with literal "" :)//MethodCall[pmd-java:matchesSig('_#equals(_)')andMethodCall[pmd-java:matchesSig('java.lang.AbstractStringBuilder#toString()')]andArgumentList/VariableAccess[@Name=//VariableDeclarator[StringLiteral[@Image='""']]/VariableId[pmd-java:modifiers()='final']/@Name]]|(: finds sb.toString().equals("") :)//MethodCall[pmd-java:matchesSig('_#equals(_)')andMethodCall[pmd-java:matchesSig('java.lang.AbstractStringBuilder#toString()')]andArgumentList/StringLiteral[@Image='""']]

Example(s):

StringBuffersb=newStringBuffer();if(sb.toString().equals("")){}// inefficientif(sb.length()==0){}// preferred

Use this rule by referencing it:

<ruleref="category/java/performance.xml/UseStringBufferLength"/>

This documentation is written in markdown.
If there is something missing or can be improved, edit this page on github and create a PR: Edit on GitHub

©2025 PMD Open Source Project. All rights reserved.
Site last generated: Sep 12, 2025

PMD                logo


[8]ページ先頭

©2009-2025 Movatter.jp