Movatterモバイル変換


[0]ホーム

URL:


 
» Error Prone Edit on GitHub

Error Prone

Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
Table of Contents

AssignmentInOperand

Since: PMD 1.03

Priority: Medium (3)

Avoid assignments in operands; this can make code more complicated and harder to read.

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

Example(s):

publicvoidbar(){intx=2;if((x=getX())==3){System.out.println("3!");}}

This rule has the following properties:

NameDefault ValueDescription
allowIffalseAllow assignment within the conditional expression of an if statement
allowForfalseAllow assignment within the conditional expression of a for statement
allowWhilefalseAllow assignment within the conditional expression of a while statement
allowIncrementDecrementfalseAllow increment or decrement operators within the conditional expression of an if, for, or while statement

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

<ruleref="category/java/errorprone.xml/AssignmentInOperand"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/AssignmentInOperand"><properties><propertyname="allowIf"value="false"/><propertyname="allowFor"value="false"/><propertyname="allowWhile"value="false"/><propertyname="allowIncrementDecrement"value="false"/></properties></rule>

AssignmentToNonFinalStatic

Since: PMD 2.2

Priority: Medium (3)

Identifies a possible unsafe usage of a static field.

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

Example(s):

publicclassStaticField{staticintx;publicFinalFields(inty){x=y;// unsafe}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AssignmentToNonFinalStatic"/>

AvoidAccessibilityAlteration

Since: PMD 4.1

Priority: Medium (3)

Methods such asgetDeclaredConstructors(),getDeclaredMethods(), andgetDeclaredFields() alsoreturn private constructors, methods and fields. These can be made accessible by callingsetAccessible(true).This gives access to normally protected data which violates the principle of encapsulation.

This rule detects calls tosetAccessible and finds possible accessibility alterations.If the call tosetAccessible is wrapped within aPrivilegedAction, then the access alterationis assumed to be deliberate and is not reported.

Note that with Java 17 the Security Manager, which is used forPrivilegedAction execution,is deprecated:JEP 411: Deprecate the Security Manager for Removal.For future-proof code, deliberate access alteration should be suppressed using the usualsuppression methods (e.g. by using@SuppressWarnings annotation).

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.reflect.AccessibleObject#setAccessible(boolean)")orpmd-java:matchesSig("_#setAccessible(java.lang.reflect.AccessibleObject[],boolean)")][not(ArgumentList/BooleanLiteral[@True=false()])](: exclude anonymous privileged action classes :)[not(ancestor::ConstructorCall[1][pmd-java:typeIs('java.security.PrivilegedAction')]/AnonymousClassDeclaration)](: exclude inner privileged action classes :)[not(ancestor::ClassDeclaration[1][pmd-java:typeIs('java.security.PrivilegedAction')])](: exclude privileged action lambdas :)[not(ancestor::LambdaExpression[pmd-java:typeIs('java.security.PrivilegedAction')])]

Example(s):

importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.security.AccessController;importjava.security.PrivilegedAction;publicclassViolation{privatevoidinvalidSetAccessCalls()throwsNoSuchMethodException,SecurityException{Constructor<?>constructor=this.getClass().getDeclaredConstructor(String.class);// call to forbidden setAccessibleconstructor.setAccessible(true);MethodprivateMethod=this.getClass().getDeclaredMethod("aPrivateMethod");// call to forbidden setAccessibleprivateMethod.setAccessible(true);// deliberate accessibility alterationStringprivateField=AccessController.doPrivileged(newPrivilegedAction<String>(){@OverridepublicStringrun(){try{Fieldfield=Violation.class.getDeclaredField("aPrivateField");field.setAccessible(true);return(String)field.get(null);}catch(ReflectiveOperationException|SecurityExceptione){thrownewRuntimeException(e);}}});}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidAccessibilityAlteration"/>

AvoidAssertAsIdentifier

Since: PMD 3.4

Priority: Medium High (2)

Maximum Language Version: Java 1.3

Use of the termassert will conflict with newer versions of Java since it is a reserved word.

Since Java 1.4, the tokenassert became a reserved word and using it as an identifier willresult in a compilation failure for Java 1.4 and later. This rule is therefore only usefulfor old Java code before Java 1.4. It can be used to identify problematic code prior to a Java update.

This rule is defined by the following XPath expression:

//VariableId[@Name='assert']

Example(s):

publicclassA{publicclassFoo{Stringassert="foo";}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidAssertAsIdentifier"/>

AvoidBranchingStatementAsLastInLoop

Since: PMD 5.0

Priority: Medium High (2)

Using a branching statement as the last part of a loop may be a bug, and/or is confusing.Ensure that the usage is not a bug, or consider using another approach.

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

Example(s):

// unusual use of branching statement in a loopfor(inti=0;i<10;i++){if(i*i<=25){continue;}break;}// this makes more sense...for(inti=0;i<10;i++){if(i*i>25){break;}}

This rule has the following properties:

NameDefault ValueDescription
checkBreakLoopTypesfor , do , whileList of loop types in which break statements will be checked
checkContinueLoopTypesfor , do , whileList of loop types in which continue statements will be checked
checkReturnLoopTypesfor , do , whileList of loop types in which return statements will be checked

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

<ruleref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"><properties><propertyname="checkBreakLoopTypes"value="for,do,while"/><propertyname="checkContinueLoopTypes"value="for,do,while"/><propertyname="checkReturnLoopTypes"value="for,do,while"/></properties></rule>

AvoidCallingFinalize

Since: PMD 3.0

Priority: Medium (3)

The method Object.finalize() is called by the garbage collector on an object when garbage collection determinesthat there are no more references to the object. It should not be invoked by application logic.

Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.Object#finalize()")](: it's ok inside finalize :)[not(SuperExpressionandancestor::*[self::MethodDeclarationorself::Initializer][1][@Name='finalize'][@Arity=0][VoidType])]

Example(s):

voidfoo(){Barb=newBar();b.finalize();}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidCallingFinalize"/>

AvoidCatchingNPE

Since: PMD 1.8

Priority: Medium (3)

Code should never throw NullPointerExceptions under normal circumstances. A catch block may hide theoriginal error, causing other, more subtle problems later on.

This rule is defined by the following XPath expression:

//CatchClause/CatchParameter/ClassType[pmd-java:typeIsExactly('java.lang.NullPointerException')]

Example(s):

publicclassFoo{voidbar(){try{// do something}catch(NullPointerExceptionnpe){}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidCatchingNPE"/>

AvoidCatchingThrowable

Since: PMD 1.2

Priority: Medium (3)

Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such asOutOfMemoryError that should be exposed and managed separately.

This rule is defined by the following XPath expression:

//CatchParameter[ClassType[pmd-java:typeIsExactly('java.lang.Throwable')]]/VariableId

Example(s):

publicvoidbar(){try{// do something}catch(Throwableth){// should not catch Throwableth.printStackTrace();}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidCatchingThrowable"/>

AvoidDecimalLiteralsInBigDecimalConstructor

Since: PMD 3.4

Priority: Medium (3)

One might assume that the result of "new BigDecimal(0.1)" is exactly equal to 0.1, but it is actuallyequal to .1000000000000000055511151231257827021181583404541015625.This is because 0.1 cannot be represented exactly as a double (or as a binary fraction of any finitelength). Thus, the long value that is being passed in to the constructor is not exactly equal to 0.1,appearances notwithstanding.

The (String) constructor, on the other hand, is perfectly predictable: ‘new BigDecimal("0.1")’ isexactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the(String) constructor be used in preference to this one.

This rule is defined by the following XPath expression:

//ConstructorCall[pmd-java:matchesSig('java.math.BigDecimal#new(double)')]

Example(s):

BigDecimalbd=newBigDecimal(1.123);// loss of precision, this would trigger the ruleBigDecimalbd=newBigDecimal("1.123");// preferred approachBigDecimalbd=newBigDecimal(12);// preferred approach, ok for integer values

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>

AvoidDuplicateLiterals

Since: PMD 1.0

Priority: Medium (3)

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.errorprone.AvoidDuplicateLiteralsRule

Example(s):

privatevoidbar(){buz("Howdy");buz("Howdy");buz("Howdy");buz("Howdy");}privatevoidbuz(Stringx){}

This rule has the following properties:

NameDefault ValueDescription
maxDuplicateLiterals4Max duplicate literals
minimumLength3Minimum string length to check
skipAnnotationsfalseSkip literals within annotations
exceptionList List of literals to ignore. A literal is ignored if its image can be found in this list. Components of this list should not be surrounded by double quotes.

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

<ruleref="category/java/errorprone.xml/AvoidDuplicateLiterals"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/AvoidDuplicateLiterals"><properties><propertyname="maxDuplicateLiterals"value="4"/><propertyname="minimumLength"value="3"/><propertyname="skipAnnotations"value="false"/><propertyname="exceptionList"value=""/></properties></rule>

AvoidEnumAsIdentifier

Since: PMD 3.4

Priority: Medium High (2)

Maximum Language Version: Java 1.4

Use of the termenum will conflict with newer versions of Java since it is a reserved word.

Since Java 1.5, the tokenenum became a reserved word and using it as an identifier willresult in a compilation failure for Java 1.5 and later. This rule is therefore only usefulfor old Java code before Java 1.5. It can be used to identify problematic code prior to a Java update.

This rule is defined by the following XPath expression:

//VariableId[@Name='enum']

Example(s):

publicclassA{publicclassFoo{Stringenum="foo";}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidEnumAsIdentifier"/>

AvoidFieldNameMatchingMethodName

Since: PMD 3.0

Priority: Medium (3)

It can be confusing to have a field name with the same name as a method. While this is permitted,having information (field) and actions (method) is not clear naming. Developers versed inSmalltalk often prefer this approach as the methods denote accessor methods.

This rule is defined by the following XPath expression:

//FieldDeclaration/VariableDeclarator/VariableId[some$methodin../../..[self::ClassBodyorself::EnumBody]/MethodDeclarationsatisfieslower-case(@Name)=lower-case($method/@Name)]

Example(s):

publicclassFoo{Objectbar;// bar is data or an action or both?voidbar(){}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidFieldNameMatchingMethodName"/>

AvoidFieldNameMatchingTypeName

Since: PMD 3.0

Priority: Medium (3)

It is somewhat confusing to have a field name matching the declaring type name.This probably means that type and/or field names should be chosen more carefully.

This rule is defined by the following XPath expression:

//FieldDeclaration/VariableDeclarator/VariableId[lower-case(@Name)=lower-case(ancestor::ClassDeclaration[1]/@SimpleName)]

Example(s):

publicclassFooextendsBar{intfoo;// There is probably a better name that can be used}publicinterfaceOperation{intOPERATION=1;// There is probably a better name that can be used}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidFieldNameMatchingTypeName"/>

AvoidInstanceofChecksInCatchClause

Since: PMD 3.0

Priority: Medium (3)

Each caught exception type should be handled in its own catch clause.

This rule is defined by the following XPath expression:

//CatchParameter/following-sibling::Block//InfixExpression[@Operator='instanceof']/VariableAccess[@Name=./ancestor::Block/preceding-sibling::CatchParameter/@Name]

Example(s):

try{// Avoid this// do something}catch(Exceptionee){if(eeinstanceofIOException){cleanup();}}try{// Prefer this:// do something}catch(IOExceptionee){cleanup();}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause"/>

AvoidLiteralsInIfCondition

Since: PMD 4.2.6

Priority: Medium (3)

Avoid using hard-coded literals in conditional statements. By declaring them as static variablesor private members with descriptive names maintainability is enhanced. By default, the literals "-1" and "0" are ignored.More exceptions can be defined with the property "ignoreMagicNumbers".

The rule doesn’t consider deeper expressions by default, but this can be enabled via the propertyignoreExpressions.With this property set to false, if-conditions likei == 1 + 5 are reported as well. Note that in that case,the property ignoreMagicNumbers is not taken into account, if there are multiple literals involved in such an expression.

This rule is defined by the following XPath expression:

(: simple case - no deep expressions - this is always executed :)//IfStatement/*[1]/*[pmd-java:nodeIs('Literal')][not(pmd-java:nodeIs('NullLiteral'))][not(pmd-java:nodeIs('BooleanLiteral'))][empty(index-of(tokenize($ignoreMagicNumbers,'\s*,\s*'),@Image))]|(: consider also deeper expressions :)//IfStatement[$ignoreExpressions=false()]/*[1]//*[not(self::UnaryExpression[@Operator='-'])]/*[pmd-java:nodeIs('Literal')][not(pmd-java:nodeIs('NullLiteral'))][not(pmd-java:nodeIs('BooleanLiteral'))][empty(index-of(tokenize($ignoreMagicNumbers,'\s*,\s*'),@Image))]|(: consider negative literals :)//IfStatement[$ignoreExpressions=false()]/*[1]//UnaryExpression[@Operator='-']/*[pmd-java:nodeIs('Literal')][not(pmd-java:nodeIs('NullLiteral'))][not(pmd-java:nodeIs('BooleanLiteral'))][empty(index-of(tokenize($ignoreMagicNumbers,'\s*,\s*'),concat('-',@Image)))]|(: consider multiple literals in expressions :)//IfStatement[$ignoreExpressions=false()]/*[1][count(*[pmd-java:nodeIs('Literal')][not(pmd-java:nodeIs('NullLiteral'))][not(pmd-java:nodeIs('BooleanLiteral'))])>1]

Example(s):

privatestaticfinalintMAX_NUMBER_OF_REQUESTS=10;publicvoidcheckRequests(){if(i==10){// magic number, buried in a methoddoSomething();}if(i==MAX_NUMBER_OF_REQUESTS){// preferred approachdoSomething();}if(aString.indexOf('.')!=-1){}// magic number -1, by default ignoredif(aString.indexOf('.')>=0){}// alternative approachif(aDouble>0.0){}// magic number 0.0if(aDouble>=Double.MIN_VALUE){}// preferred approach// with rule property "ignoreExpressions" set to "false"if(i==pos+5){}// violation: magic number 5 within an (additive) expressionif(i==pos+SUFFIX_LENGTH){}// preferred approachif(i==5&&"none".equals(aString)){}// 2 violations: magic number 5 and literal "none"}

This rule has the following properties:

NameDefault ValueDescription
ignoreMagicNumbers-1,0Comma-separated list of magic numbers, that should be ignored
ignoreExpressionstrueIf true, only literals in simple if conditions are considered. Otherwise literals in expressions are checked, too.

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

<ruleref="category/java/errorprone.xml/AvoidLiteralsInIfCondition"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/AvoidLiteralsInIfCondition"><properties><propertyname="ignoreMagicNumbers"value="-1,0"/><propertyname="ignoreExpressions"value="true"/></properties></rule>

AvoidLosingExceptionInformation

Since: PMD 4.2.6

Priority: Medium High (2)

Statements in a catch block that invoke accessors on the exception without using the informationonly add to code size. Either remove the invocation, or use the return result.

This rule is defined by the following XPath expression:

//CatchClause/Block/ExpressionStatement/MethodCall[pmd-java:matchesSig("java.lang.Throwable#getMessage()")orpmd-java:matchesSig("java.lang.Throwable#getLocalizedMessage()")orpmd-java:matchesSig("java.lang.Throwable#getCause()")orpmd-java:matchesSig("java.lang.Throwable#getStackTrace()")orpmd-java:matchesSig("java.lang.Object#toString()")]

Example(s):

publicvoidbar(){try{// do something}catch(SomeExceptionse){se.getMessage();}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidLosingExceptionInformation"/>

AvoidMultipleUnaryOperators

Since: PMD 4.2

Priority: Medium High (2)

The use of multiple unary operators may be problematic, and/or confusing.Ensure that the intended usage is not a bug, or consider simplifying the expression.

This rule is defined by the following XPath expression:

(: Only report on the toplevel one :)//UnaryExpression[UnaryExpressionandnot(parent::UnaryExpression)]

Example(s):

// These are typo bugs, or at best needlessly complex and confusing:inti=--1;intj=+-+1;intz=~~2;booleanb=!!true;booleanc=!!!true;// These are better:inti=1;intj=-1;intz=2;booleanb=true;booleanc=false;// And these just make your brain hurt:inti=~-2;intj=-~7;

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/AvoidMultipleUnaryOperators"/>

AvoidUsingOctalValues

Since: PMD 3.9

Priority: Medium (3)

Integer literals should not start with zero since this denotes that the rest of literal will beinterpreted as an octal value.

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

Example(s):

inti=012;// set i with 10 not 12intj=010;// set j with 8 not 10k=i*j;// set k with 80 not 120

This rule has the following properties:

NameDefault ValueDescription
strictfalseDetect violations between 00 and 07

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

<ruleref="category/java/errorprone.xml/AvoidUsingOctalValues"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/AvoidUsingOctalValues"><properties><propertyname="strict"value="false"/></properties></rule>

BrokenNullCheck

Since: PMD 3.8

Priority: Medium High (2)

The null check is broken since it will throw a NullPointerException itself.It is likely that you used || instead of && or vice versa.

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

Example(s):

publicStringbar(Stringstring){// should be &&if(string!=null||!string.equals(""))returnstring;// should be ||if(string==null&&string.equals(""))returnstring;}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/BrokenNullCheck"/>

CallSuperFirst

Since: PMD 4.2.5

Priority: Medium (3)

Super should be called at the start of the method

This rule is defined by the following XPath expression:

//ClassDeclaration[pmd-java:typeIs('android.app.Activity')orpmd-java:typeIs('android.app.Application')orpmd-java:typeIs('android.app.Service')]//MethodDeclaration[@Name=('onCreate','onConfigurationChanged','onPostCreate','onPostResume','onRestart','onRestoreInstanceState','onResume','onStart')][not(Block/*[1]/MethodCall[SuperExpression][@MethodName=ancestor::MethodDeclaration/@Name])]

Example(s):

importandroid.app.Activity;importandroid.os.Bundle;publicclassDummyActivityextendsActivity{publicvoidonCreate(Bundlebundle){// missing call to super.onCreate(bundle)foo();}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CallSuperFirst"/>

CallSuperLast

Since: PMD 4.2.5

Priority: Medium (3)

Super should be called at the end of the method

This rule is defined by the following XPath expression:

//ClassDeclaration[pmd-java:typeIs('android.app.Activity')orpmd-java:typeIs('android.app.Application')orpmd-java:typeIs('android.app.Service')]//MethodDeclaration[@Name=('finish','onDestroy','onPause','onSaveInstanceState','onStop','onTerminate')][not(Block/*[last()]/MethodCall[SuperExpression][@MethodName=ancestor::MethodDeclaration/@Name])]

Example(s):

importandroid.app.Activity;publicclassDummyActivityextendsActivity{publicvoidonPause(){foo();// missing call to super.onPause()}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CallSuperLast"/>

CheckSkipResult

Since: PMD 5.0

Priority: Medium (3)

The skip() method may skip a smaller number of bytes than requested. Check the returned value to find out if it was the case or not.

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

Example(s):

publicclassFoo{privateFileInputStream_s=newFileInputStream("file");publicvoidskip(intn)throwsIOException{_s.skip(n);// You are not sure that exactly n bytes are skipped}publicvoidskipExactly(intn)throwsIOException{while(n!=0){longskipped=_s.skip(n);if(skipped==0)thrownewEOFException();n-=skipped;}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CheckSkipResult"/>

ClassCastExceptionWithToArray

Since: PMD 3.4

Priority: Medium (3)

When deriving an array of a specific class from your Collection, one should provide an array ofthe same class as the parameter of thetoArray() method. Doing otherwise will resultin aClassCastException.

This rule is defined by the following XPath expression:

//CastExpression[ArrayType/ClassType[not(pmd-java:typeIsExactly('java.lang.Object'))]]/MethodCall[pmd-java:matchesSig("java.util.Collection#toArray()")]

Example(s):

Collectionc=newArrayList();Integerobj=newInteger(1);c.add(obj);// this would trigger the rule (and throw a ClassCastException if executed)Integer[]a=(Integer[])c.toArray();// this is fine and will not trigger the ruleInteger[]b=(Integer[])c.toArray(newInteger[0]);

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ClassCastExceptionWithToArray"/>

CloneMethodMustBePublic

Since: PMD 5.4.0

Priority: Medium (3)

The java manual says "By convention, classes that implement this interface should overrideObject.clone (which is protected) with a public method."

This rule is defined by the following XPath expression:

//MethodDeclaration[not(pmd-java:modifiers()="public")][@Name='clone'][@Arity=0]

Example(s):

publicclassFooimplementsCloneable{@OverrideprotectedObjectclone()throwsCloneNotSupportedException{// Violation, must be public}}publicclassFooimplementsCloneable{@OverrideprotectedFooclone(){// Violation, must be public}}publicclassFooimplementsCloneable{@OverridepublicObjectclone()// Ok}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CloneMethodMustBePublic"/>

CloneMethodMustImplementCloneable

Since: PMD 1.9

Priority: Medium (3)

The method clone() should only be implemented if the class implements the Cloneable interface with the exception ofa final method that only throws CloneNotSupportedException.

The rule can also detect, if the class implements or extends a Cloneable class.

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

Example(s):

publicclassMyClass{publicObjectclone()throwsCloneNotSupportedException{returnfoo;}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CloneMethodMustImplementCloneable"/>

CloneMethodReturnTypeMustMatchClassName

Since: PMD 5.4.0

Priority: Medium (3)

Minimum Language Version: Java 1.5

If a class implementsCloneable the return type of the methodclone() must be the class name. That way, the callerof the clone method doesn’t need to cast the returned clone to the correct type.

Note: Such a covariant return type is only possible with Java 1.5 or higher.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name='clone'][@Arity=0][ClassType[1]/@SimpleName!=ancestor::ClassDeclaration[1]/@SimpleName]

Example(s):

publicclassFooimplementsCloneable{@OverrideprotectedObjectclone(){// Violation, Object must be Foo}}publicclassFooimplementsCloneable{@OverridepublicFooclone(){//Ok}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName"/>

CloseResource

Since: PMD 1.2.2

Priority: Medium (3)

Ensure that resources (likejava.sql.Connection,java.sql.Statement, andjava.sql.ResultSet objectsand any subtype ofjava.lang.AutoCloseable) are always closed after use.Failing to do so might result in resource leaks.

Note: It suffices to configure the super type, e.g.java.lang.AutoCloseable, so that this rule automatically triggerson any subtype (e.g.java.io.FileInputStream). Additionally specifyingjava.sql.Connection helps in detectingthe types, if the type resolution / auxclasspath is not correctly setup.

Note: Since PMD 6.16.0 the default value for the propertytypes containsjava.lang.AutoCloseable and detectsnow cases where the standardjava.io.*Stream classes are involved. In order to restore the old behaviour,just remove "AutoCloseable" from the types.

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

Example(s):

publicclassBar{publicvoidwithSQL(){Connectionc=pool.getConnection();try{// do stuff}catch(SQLExceptionex){// handle exception}finally{// oops, should close the connection using 'close'!// c.close();}}publicvoidwithFile(){InputStreamfile=newFileInputStream(newFile("/tmp/foo"));try{intc=file.in();}catch(IOExceptione){// handle exception}finally{// TODO: close file}}}

This rule has the following properties:

NameDefault ValueDescription
closeTargets Methods which may close this resource
typesjava.lang.AutoCloseable , java.sql.Connection , java.sql.Statement , java.sql.ResultSetAffected types
closeAsDefaultTargettrueConsider ‘close’ as a target by default
allowedResourceTypesjava.io.ByteArrayOutputStream , java.io.ByteArrayInputStream , java.io.StringWriter , java.io.CharArrayWriter , java.util.stream.Stream , java.util.stream.IntStream , java.util.stream.LongStream , java.util.stream.DoubleStreamExact class names that do not need to be closed
closeNotInFinallyfalseDetect if ‘close’ (or other closeTargets) is called outside of a finally-block

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

<ruleref="category/java/errorprone.xml/CloseResource"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/CloseResource"><properties><propertyname="closeTargets"value=""/><propertyname="types"value="java.lang.AutoCloseable,java.sql.Connection,java.sql.Statement,java.sql.ResultSet"/><propertyname="closeAsDefaultTarget"value="true"/><propertyname="allowedResourceTypes"value="java.io.ByteArrayOutputStream,java.io.ByteArrayInputStream,java.io.StringWriter,java.io.CharArrayWriter,java.util.stream.Stream,java.util.stream.IntStream,java.util.stream.LongStream,java.util.stream.DoubleStream"/><propertyname="closeNotInFinally"value="false"/></properties></rule>

CompareObjectsWithEquals

Since: PMD 3.2

Priority: Medium (3)

Useequals() to compare object references; avoid comparing them with==.

Since comparing objects with named constants is useful in some cases (eg, whendefining constants for sentinel values), the rule ignores comparisons againstfields with all-caps name (egthis == SENTINEL), which is a common namingconvention for constant fields.

You may allow some types to be compared by reference by listing the exceptionsin thetypesThatCompareByReference property.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator=("==","!=")][count(*[not(self::NullLiteral)][pmd-java:typeIs('java.lang.Object')][not(some$tin$typesThatCompareByReferencesatisfiespmd-java:typeIs($t))])=2][not(ancestor::MethodDeclaration[1][@Name="equals"])](: Is not a field access with an all-caps identifier :)[not(FieldAccess[upper-case(@Name)=@Name]orVariableAccess[upper-case(@Name)=@Name])]

Example(s):

classFoo{booleanbar(Stringa,Stringb){returna==b;}}

This rule has the following properties:

NameDefault ValueDescription
typesThatCompareByReferencejava.lang.Enum , java.lang.ClassList of canonical type names for which reference comparison is allowed.

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

<ruleref="category/java/errorprone.xml/CompareObjectsWithEquals"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/CompareObjectsWithEquals"><properties><propertyname="typesThatCompareByReference"value="java.lang.Enum,java.lang.Class"/></properties></rule>

ComparisonWithNaN

Since: PMD 6.36.0

Priority: Medium (3)

Reports comparisons with double and floatNaN (Not-a-Number) values.These arespecifiedto have unintuitive behavior: NaN is considered unequal to itself.This means a check likesomeDouble == Double.NaN will always returnfalse, even ifsomeDouble is really the NaN value. To test whether avalue is the NaN value, one should instead useDouble.isNaN(someDouble)(orFloat.isNaN). The!= operator should be treated similarly.Finally, comparisons likesomeDouble <= Double.NaN are nonsensicaland will always evaluate to false.

This rule has been renamed from "BadComparison" in PMD 6.36.0.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator=("==","!=","<=",">=","<",">")]/FieldAccess[@Name='NaN'and(pmd-java:typeIs('double')orpmd-java:typeIs('float'))]

Example(s):

booleanx=(y==Double.NaN);

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ComparisonWithNaN"/>

ConfusingArgumentToVarargsMethod

Since: PMD 7.1.0

Priority: Medium (3)

Reports a confusing argument passed to a varargs method.

This can occur when an array is passed as a single varargs argument, when the array type is not exactly thetype of array that the varargs method expects. If, that array is a subtype of the component type of the expectedarray type, then it might not be clear what value the called varargs method will receive.For instance if you have:

voidvarargs(Object...parm);

and call it like so:

varargs(newString[]{"a"});

it is not clear whether you intended the method to receive the valuenew Object[]{ new String[] {"a"} } orjustnew String[] {"a"} (the latter happens). This confusion occurs becauseString[] is both a subtypeofObject[] and ofObject. To clarify your intent in this case, use a cast or pass individual elements like so:

// varargs call// parm will be `new Object[] { "a" }`varargs("a");// non-varargs call// parm will be `new String[] { "a" }`varargs((Object[])newString[]{"a"});// varargs call// parm will be `new Object[] { new String[] { "a" } }`varargs((Object)newString[]{"a"});

Another confusing case is when you passnull as the varargs argument. Here it is not clear whether you intendedto pass an array with a single null element, or a null array (the latter happens). This can similarly be clarifiedwith a cast.

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

Example(s):

importjava.util.Arrays;abstractclassC{abstractvoidvarargs(Object...args);static{varargs(newString[]{"a"});varargs(null);}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ConfusingArgumentToVarargsMethod"/>

ConstructorCallsOverridableMethod

Since: PMD 1.04

Priority: High (1)

Reports calls to overridable methods onthis during object initialization. Theseare invoked on an incompletely constructed object and can be difficult to debug if overridden.This is because the subclass usually assumes that the superclass is completely initializedin all methods. If that is not the case, bugs can appear in the constructor, for instance,some fields that are still null may cause a NullPointerException or be stored somewhereelse to blow up later.

To avoid this problem, only use methods that are static, private, or final in constructors.Note that those methods also must not call overridable methods transitively to be safe.

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

Example(s):

publicclassSeniorClass{publicSeniorClass(){toString();//may throw NullPointerException if overridden}publicStringtoString(){return"IAmSeniorClass";}}publicclassJuniorClassextendsSeniorClass{privateStringname;publicJuniorClass(){super();//Automatic call leads to NullPointerExceptionname="JuniorClass";}publicStringtoString(){returnname.toUpperCase();}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ConstructorCallsOverridableMethod"/>

DetachedTestCase

Since: PMD 6.13.0

Priority: Medium (3)

The method appears to be a test case since it has public or default visibility,non-static access, no arguments, no return value, has no annotations, but is amember of a class that has one or more JUnit test cases. If it is a utilitymethod, it should likely have private visibility. If it is an ignored test, itshould be annotated with @Test and @Ignore.

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

Example(s):

publicclassMyTest{@TestpublicvoidsomeTest(){}// violation: Not annotatedpublicvoidsomeOtherTest(){}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DetachedTestCase"/>

DoNotCallGarbageCollectionExplicitly

Since: PMD 4.2

Priority: Medium High (2)

Calls toSystem.gc(),Runtime.getRuntime().gc(), andSystem.runFinalization() are not advised.Code should have the same behavior whether the garbage collection is disabled using the option-Xdisableexplicitgc or not.

Moreover, "modern" JVMs do a very good job handling garbage collections. If memory usage issues unrelated to memoryleaks develop within an application, it should be dealt with JVM options rather than within the code itself.

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.System#gc()")orpmd-java:matchesSig("java.lang.Runtime#gc()")orpmd-java:matchesSig("java.lang.System#runFinalization()")orpmd-java:matchesSig("java.lang.Runtime#runFinalization()")]

Example(s):

publicclassGCCall{publicGCCall(){// Explicit gc call !System.gc();}publicvoiddoSomething(){// Explicit gc call !Runtime.getRuntime().gc();}publicexplicitGCcall(){// Explicit gc call !System.gc();}publicvoiddoSomething(){// Explicit gc call !Runtime.getRuntime().gc();}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly"/>

DoNotExtendJavaLangThrowable

Since: PMD 6.0.0

Priority: Medium (3)

Extend Exception or RuntimeException instead of Throwable.

This rule is defined by the following XPath expression:

//ClassDeclaration/ExtendsList/ClassType[pmd-java:typeIsExactly('java.lang.Throwable')]

Example(s):

publicclassFooextendsThrowable{}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DoNotExtendJavaLangThrowable"/>

DoNotHardCodeSDCard

Since: PMD 4.2.6

Priority: Medium (3)

Use Environment.getExternalStorageDirectory() instead of "/sdcard"

This rule is defined by the following XPath expression:

//StringLiteral[starts-with(@Image,'"/sdcard')]

Example(s):

publicclassMyActivityextendsActivity{protectedvoidfoo(){StringstorageLocation="/sdcard/mypackage";// hard-coded, poor approachstorageLocation=Environment.getExternalStorageDirectory()+"/mypackage";// preferred approach}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DoNotHardCodeSDCard"/>

DoNotTerminateVM

Since: PMD 4.1

Priority: Medium (3)

Web applications should not callSystem.exit(), since only the web container or theapplication server should stop the JVM. Otherwise a web application would terminate all other applicationsrunning on the same application server.

This rule also checks for the equivalent callsRuntime.getRuntime().exit() andRuntime.getRuntime().halt().

This rule has been renamed from "DoNotCallSystemExit" in PMD 6.29.0.

This rule is defined by the following XPath expression:

//(MethodDeclaration[@MainMethod=false()]|Initializer)//MethodCall[pmd-java:matchesSig("java.lang.System#exit(int)")orpmd-java:matchesSig("java.lang.Runtime#exit(int)")orpmd-java:matchesSig("java.lang.Runtime#halt(int)")]

Example(s):

publicvoidbar(){System.exit(0);// never call this when running in an application server!}publicvoidfoo(){Runtime.getRuntime().exit(0);// never stop the JVM manually, the container will do this.}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DoNotTerminateVM"/>

DoNotThrowExceptionInFinally

Since: PMD 4.2

Priority: Medium Low (4)

Throwing exceptions within a ‘finally’ block is confusing since they may mask other exceptionsor code defects.Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block"

This rule is defined by the following XPath expression:

//FinallyClause[descendant::ThrowStatement]

Example(s):

publicclassFoo{publicvoidbar(){try{// Here do some stuff}catch(Exceptione){// Handling the issue}finally{// is this really a good idea ?thrownewException();}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DoNotThrowExceptionInFinally"/>

DontImportSun

Since: PMD 1.5

Priority: Medium Low (4)

Avoid importing anything from the ‘sun.*’ packages. These packages are not portableand are likely to change.

If you find yourself having to depend on Sun APIs, confine this dependency to assmall a scope as possible, for instance by writing a stable wrapper class aroundthe unstable API. You can then suppress this rule in the implementation of the wrapper.

This rule is defined by the following XPath expression:

//ImportDeclaration[starts-with(@ImportedName,'sun.')]

Example(s):

importsun.misc.foo;publicclassFoo{}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DontImportSun"/>

DontUseFloatTypeForLoopIndices

Since: PMD 4.3

Priority: Medium (3)

Don’t use floating point for loop indices. If you must use floating point, use doubleunless you’re certain that float provides enough precision and you have a compellingperformance need (space or time).

This rule is defined by the following XPath expression:

//ForStatement/ForInit//VariableId[pmd-java:typeIs('float')]

Example(s):

publicclassCount{publicstaticvoidmain(String[]args){finalintSTART=2000000000;intcount=0;for(floatf=START;f<START+50;f++)count++;//Prints 0 because (float) START == (float) (START + 50).System.out.println(count);//The termination test misbehaves due to floating point granularity.}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices"/>

EmptyCatchBlock

Since: PMD 0.1

Priority: Medium (3)

Empty Catch Block finds instances where an exception is caught, but nothing is done.In most circumstances, this swallows an exception which should either be acted onor reported.

This rule is defined by the following XPath expression:

//CatchClause[Block[count(*)=0and($allowCommentedBlocks=false()or@containsComment=false())]andCatchParameter/VariableId[not(matches(@Name,$allowExceptionNameRegex))]]

Example(s):

publicvoiddoSomething(){try{FileInputStreamfis=newFileInputStream("/tmp/bugger");}catch(IOExceptionioe){// not good}}

This rule has the following properties:

NameDefault ValueDescription
allowCommentedBlocksfalseEmpty blocks containing comments will be skipped
allowExceptionNameRegex^(ignored|expected)$Empty blocks catching exceptions with names matching this regular expression will be skipped

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

<ruleref="category/java/errorprone.xml/EmptyCatchBlock"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/EmptyCatchBlock"><properties><propertyname="allowCommentedBlocks"value="false"/><propertyname="allowExceptionNameRegex"value="^(ignored|expected)$"/></properties></rule>

EmptyFinalizer

Since: PMD 1.5

Priority: Medium (3)

Empty finalize methods serve no purpose and should be removed. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name='finalize'][@Arity=0]/Block[not(*)]

Example(s):

publicclassFoo{protectedvoidfinalize(){}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/EmptyFinalizer"/>

EqualsNull

Since: PMD 1.9

Priority: High (1)

Tests for null should not use the equals() method. The ‘==’ operator should be used instead.

This rule is defined by the following XPath expression:

//MethodCall[@MethodName="equals"andArgumentList[count(*)=1andNullLiteral]]

Example(s):

Stringx="foo";if(x.equals(null)){// bad formdoSomething();}if(x==null){// preferreddoSomething();}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/EqualsNull"/>

FinalizeDoesNotCallSuperFinalize

Since: PMD 1.5

Priority: Medium (3)

If the finalize() is implemented, its last action should be to call super.finalize. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name="finalize"][@Arity=0]/Block/*[last()][not(MethodCall[@MethodName="finalize"]/SuperExpression)][not(FinallyClause/Block/ExpressionStatement/MethodCall[@MethodName="finalize"]/SuperExpression)]

Example(s):

protectedvoidfinalize(){something();// neglected to call super.finalize()}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize"/>

FinalizeOnlyCallsSuperFinalize

Since: PMD 1.5

Priority: Medium (3)

If the finalize() is implemented, it should do something besides just calling super.finalize(). Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name='finalize'][@Arity=0][Block[@Size=1]/ExpressionStatement/MethodCall[@MethodName="finalize"][SuperExpression]]

Example(s):

protectedvoidfinalize(){super.finalize();}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize"/>

FinalizeOverloaded

Since: PMD 1.5

Priority: Medium (3)

Methods named finalize() should not have parameters. It is confusing and most likely an attempt tooverload Object.finalize(). It will not be called by the VM.

Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name='finalize'][@Arity>0]

Example(s):

publicclassFoo{// this is confusing and probably a bugprotectedvoidfinalize(inta){}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/FinalizeOverloaded"/>

FinalizeShouldBeProtected

Since: PMD 1.1

Priority: Medium (3)

When overriding the finalize(), the new method should be set as protected. If made public,other classes may invoke it at inappropriate times.

Note that Oracle has declared Object.finalize() as deprecated since JDK 9.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Visibility!="protected"][@Name='finalize'][@Arity=0]

Example(s):

publicvoidfinalize(){// do something}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/FinalizeShouldBeProtected"/>

IdempotentOperations

Since: PMD 2.0

Priority: Medium (3)

Avoid idempotent operations - they have no effect.

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

Example(s):

publicclassFoo{publicvoidbar(){intx=2;x=x;}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/IdempotentOperations"/>

ImplicitSwitchFallThrough

Since: PMD 3.0

Priority: Medium (3)

Switch statements without break or return statements for each case optionmay indicate problematic behaviour. Empty cases are ignored as these indicatean intentional fall-through.

You can ignore a violation by commenting// fallthrough before the case labelwhich is reached by fallthrough, or with@SuppressWarnings("fallthrough").

This rule has been renamed from "MissingBreakInSwitch" in PMD 6.37.0.

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

Example(s):

publicvoidbar(intstatus){switch(status){caseCANCELLED:doCancelled();// break; hm, should this be commented out?caseNEW:doNew();// is this really a fall-through?// what happens if you add another case after this one?caseREMOVED:doRemoved();// fallthrough - this comment just clarifies that you want a fallthroughcaseOTHER:// empty case - this is interpreted as an intentional fall-throughcaseERROR:doErrorHandling();break;}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ImplicitSwitchFallThrough"/>

InstantiationToGetClass

Since: PMD 2.0

Priority: Medium Low (4)

Avoid instantiating an object just to call getClass() on it; use the .class public member instead.

This rule is defined by the following XPath expression:

//MethodCall[@MethodName='getClass'][ConstructorCall]

Example(s):

// replace thisClassc=newString().getClass();// with this:Classc=String.class;

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/InstantiationToGetClass"/>

InvalidLogMessageFormat

Since: PMD 5.5.0

Priority: Low (5)

Check for messages in slf4j and log4j2 (since 6.19.0) loggers with non matching number of arguments and placeholders.

Since 6.32.0 in addition to parameterized message placeholders ({}) also format specifiers of string formattedmessages are supported (%s).

This rule has been renamed from "InvalidSlf4jMessageFormat" in PMD 6.19.0.

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

Example(s):

LOGGER.error("forget the arg {}");LOGGER.error("forget the arg %s");LOGGER.error("too many args {}","arg1","arg2");LOGGER.error("param {}","arg1",newIllegalStateException("arg"));//The exception is shown separately, so is correct.

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/InvalidLogMessageFormat"/>

JumbledIncrementer

Since: PMD 1.0

Priority: Medium (3)

Avoid jumbled loop incrementers - it’s usually a mistake, and is confusing even if intentional.

This rule is defined by the following XPath expression:

//ForStatement[not(ForInit)orForInit//VariableId/@Name!=ForUpdate//VariableAccess/@Name][ForUpdate//VariableAccess[@AccessType='WRITE']/@Name=ancestor::ForStatement/ForInit//VariableId/@Name]

Example(s):

publicclassJumbledIncrementerRule1{publicvoidfoo(){for(inti=0;i<10;i++){// only references 'i'for(intk=0;k<20;i++){// references both 'i' and 'k'System.out.println("Hello");}}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/JumbledIncrementer"/>

JUnitSpelling

Since: PMD 1.0

Priority: Medium (3)

In JUnit 3, the setUp method is used to set up all data entities required in running tests.The tearDown method is used to clean up all data entities required in running tests.You should not misspell method name if you want your test to set up and clean up everything correctly.

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

Example(s):

importjunit.framework.*;publicclassFooextendsTestCase{publicvoidsetup(){}// oops, should be setUppublicvoidTearDown(){}// oops, should be tearDown}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/JUnitSpelling"/>

JUnitStaticSuite

Since: PMD 1.0

Priority: Medium (3)

The suite() method in a JUnit test needs to be both public and static.

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

Example(s):

importjunit.framework.*;publicclassFooextendsTestCase{publicvoidsuite(){}// oops, should be static}
importjunit.framework.*;publicclassFooextendsTestCase{privatestaticvoidsuite(){}// oops, should be public}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/JUnitStaticSuite"/>

MethodWithSameNameAsEnclosingClass

Since: PMD 1.5

Priority: Medium (3)

A method should not have the same name as its containing class.This would be confusing as it would look like a constructor.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name=ancestor::ClassDeclaration/@SimpleName]

Example(s):

publicclassMyClass{publicMyClass(){}// this is OK because it is a constructorpublicvoidMyClass(){}// this is bad because it is a method}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/MethodWithSameNameAsEnclosingClass"/>

MisplacedNullCheck

Since: PMD 3.5

Priority: Medium (3)

The null check here is misplaced. If the variable is null aNullPointerException will be thrown.Either the check is useless (the variable will never benull) or it is incorrect.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator='&&']/InfixExpression[@Operator='!='](: one side is null :)[NullLiteral](: other side checks for the variable used somewhere in the first child of conditional and expression :)[VariableAccess][some$varinpreceding-sibling::*//VariableAccess[parent::MethodCallorparent::FieldAccess][not(ancestor::InfixExpression[@Operator='||'])]/@Namesatisfies$var=VariableAccess/@Name]/VariableAccess|//InfixExpression[@Operator='||']/InfixExpression[@Operator='=='](: one side is null :)[NullLiteral](: other side checks for the variable used somewhere in the first child of conditional or expression :)[VariableAccess][some$varinpreceding-sibling::*//VariableAccess[parent::MethodCallorparent::FieldAccess][not(ancestor::InfixExpression[@Operator='&&'])]/@Namesatisfies$var=VariableAccess/@Name]/VariableAccess

Example(s):

publicclassFoo{voidbar(){if(a.equals(baz)&&a!=null){}// a could be null, misplaced null checkif(a!=null&&a.equals(baz)){}// correct null check}}
publicclassFoo{voidbar(){if(a.equals(baz)||a==null){}// a could be null, misplaced null checkif(a==null||a.equals(baz)){}// correct null check}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/MisplacedNullCheck"/>

MissingSerialVersionUID

Since: PMD 3.0

Priority: Medium (3)

Serializable classes should provide a serialVersionUID field.The serialVersionUID field is also needed for abstract base classes. Each individual class in the inheritancechain needs an own serialVersionUID field. See alsoShould an abstract class have a serialVersionUID.

This rule is defined by the following XPath expression:

//ClassDeclaration[@Interface=false()][count(ClassBody/FieldDeclaration/VariableDeclarator/VariableId[@Name='serialVersionUID'])=0][(ImplementsList|ExtendsList)/ClassType[pmd-java:typeIs('java.io.Serializable')]]

Example(s):

publicclassFooimplementsjava.io.Serializable{Stringname;// Define serialization id to avoid serialization related bugs// i.e., public static final long serialVersionUID = 4328743;}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/MissingSerialVersionUID"/>

MissingStaticMethodInNonInstantiatableClass

Since: PMD 3.0

Priority: Medium (3)

A class that has private constructors and does not have any static methods or fields cannot be used.

When one of the private constructors is annotated with one of the annotations, then the class is not considerednon-instantiatable anymore and no violation will be reported.See the propertyannotations.

This rule is defined by the following XPath expression:

let$topLevelClass:=/*/ClassDeclarationreturnlet$isLombokUtility:=exists($topLevelClass[pmd-java:hasAnnotation('lombok.experimental.UtilityClass')])return$topLevelClass[(: non-instantiable :)$isLombokUtilityor((: no lombok produced constructors :)not(pmd-java:hasAnnotation('lombok.NoArgsConstructor')orpmd-java:hasAnnotation('lombok.RequiredArgsConstructor')orpmd-java:hasAnnotation('lombok.AllArgsConstructor')orpmd-java:hasAnnotation('lombok.Builder'))and(: or has non-default constructors … :)ClassBody/ConstructorDeclarationand(: … but only private … :)not(ClassBody/ConstructorDeclaration[@Visibility!="private"])and(: … and none annotated … :)(every$xin$annotationssatisfiesnot(ClassBody/ConstructorDeclaration/ModifierList/Annotation[pmd-java:typeIs($x)])))][(: With no visible static methods … :)not(ClassBody/MethodDeclaration[($isLombokUtilityorpmd-java:modifiers()="static")and@Visibility!="private"])and(: … nor fields … :)not(ClassBody/FieldDeclaration[($isLombokUtilityorpmd-java:modifiers()="static")and@Visibility!="private"])and(: … no nested classes, that are non-private and static … :)not(ClassBody/ClassDeclaration[pmd-java:modifiers()="static"and@Visibility!="private"](: … and a non-private method returning the outer class type … :)[(ClassBody/MethodDeclaration[@Visibility!="private"][descendant::ReturnStatement/*[1][pmd-java:typeIs(ancestor::ClassDeclaration[@Nested=false()]/@BinaryName)]])or((: … or the inner class extends the outer class :)ExtendsList/ClassType[@SimpleName=ancestor::ClassDeclaration[@Nested=false()]/@SimpleName])])]

Example(s):

// This class is unusable, since it cannot be// instantiated (private constructor),// and no static method can be called.publicclassFoo{privateFoo(){}voidfoo(){}}

This rule has the following properties:

NameDefault ValueDescription
annotationsorg.springframework.beans.factory.annotation.Autowired , javax.inject.Inject , com.google.inject.Inject , lombok.BuilderIf a constructor is annotated with one of these annotations, then the class is ignored.

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

<ruleref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"><properties><propertyname="annotations"value="org.springframework.beans.factory.annotation.Autowired,javax.inject.Inject,com.google.inject.Inject,lombok.Builder"/></properties></rule>

MoreThanOneLogger

Since: PMD 2.0

Priority: Medium High (2)

Normally only one logger is used in each class. This rule supports slf4j, log4j, Java Util Logging andlog4j2 (since 6.19.0).

This rule is defined by the following XPath expression:

//ClassDeclaration[count(ClassBody/FieldDeclaration/ClassType[pmd-java:typeIs("org.apache.log4j.Logger")orpmd-java:typeIs("org.apache.logging.log4j.Logger")orpmd-java:typeIs("java.util.logging.Logger")orpmd-java:typeIs("org.slf4j.Logger")])>1]

Example(s):

publicclassFoo{Loggerlog=Logger.getLogger(Foo.class.getName());// It is very rare to see two loggers on a class, normally// log information is multiplexed by levelsLoggerlog2=Logger.getLogger(Foo.class.getName());}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/MoreThanOneLogger"/>

NonCaseLabelInSwitch

Since: PMD 1.5

Priority: Medium (3)

A non-case label (e.g. a named break/continue label) was present in a switch statement or switch expression.This is legal, but confusing. It is easy to mix up the case labels and the non-case labels.

Note: This rule was renamed fromNonCaseLabelInSwitchStatement with PMD 7.7.0.

This rule is defined by the following XPath expression:

//(SwitchStatement|SwitchExpression)//LabeledStatement

Example(s):

publicclassFoo{voidbar(inta){switch(a){case1:// do somethingmylabel:// this is legal, but confusing!break;default:break;}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/NonCaseLabelInSwitch"/>

NonCaseLabelInSwitchStatement

Deprecated

This rule has been renamed. Use instead:NonCaseLabelInSwitch

Deprecated

Since: PMD 1.5

Priority: Medium (3)

A non-case label (e.g. a named break/continue label) was present in a switch statement or switch expression.This is legal, but confusing. It is easy to mix up the case labels and the non-case labels.

Note: This rule was renamed fromNonCaseLabelInSwitchStatement with PMD 7.7.0.

This rule is defined by the following XPath expression:

//(SwitchStatement|SwitchExpression)//LabeledStatement

Example(s):

publicclassFoo{voidbar(inta){switch(a){case1:// do somethingmylabel:// this is legal, but confusing!break;default:break;}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/>

NonSerializableClass

Since: PMD 1.1

Priority: Medium (3)

If a class is marked asSerializable, then all fields need to be serializable as well. In order to excludea field, it can be marked as transient. Static fields are not considered.

This rule reports all fields, that are not serializable.

If a class implements the methods to perform manual serialization (writeObject,readObject) or usesa replacement object (writeReplace,readResolve) then this class is ignored.

Note: This rule has been revamped with PMD 6.52.0. It was previously called "BeanMembersShouldSerialize".The propertyprefix has been deprecated, since in a serializable class all fields have to beserializable regardless of the name.

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

Example(s):

classBuzzimplementsjava.io.Serializable{privatestaticfinallongserialVersionUID=1L;privatetransientintsomeFoo;// good, it's transientprivatestaticintotherFoo;// also OK, it's staticprivatejava.io.FileInputStreamstream;// bad - FileInputStream is not serializablepublicvoidsetStream(FileInputStreamstream){this.stream=stream;}publicintgetSomeFoo(){returnthis.someFoo;}}

This rule has the following properties:

NameDefault ValueDescription
checkAbstractTypesfalseEnable to verify fields with abstract types like abstract classes, interfaces, generic types or java.lang.Object. Enabling this might lead to more false positives, since the concrete runtime type can actually be serializable.

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

<ruleref="category/java/errorprone.xml/NonSerializableClass"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/NonSerializableClass"><properties><propertyname="checkAbstractTypes"value="false"/></properties></rule>

NonStaticInitializer

Since: PMD 1.5

Priority: Medium (3)

A non-static initializer block will be called any time a constructor is invoked (just prior toinvoking the constructor). While this is a valid language construct, it is rarely used and isconfusing.

This rule is defined by the following XPath expression:

//Initializer[@Static=false()][not(ancestor::*[3][self::ConstructorCallorself::EnumConstant])]

Example(s):

publicclassMyClass{// this block gets run before any call to a constructor{System.out.println("I am about to construct myself");}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/NonStaticInitializer"/>

NullAssignment

Since: PMD 1.02

Priority: Medium (3)

Assigning a "null" to a variable (outside of its declaration) is usually bad form. Sometimes, this typeof assignment is an indication that the programmer doesn’t completely understand what is going on in the code.

NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection.

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

Example(s):

publicvoidbar(){Objectx=null;// this is OKx=newObject();// big, complex piece of code herex=null;// this is not required// big, complex piece of code here}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/NullAssignment"/>

OverrideBothEqualsAndHashcode

Since: PMD 0.4

Priority: Medium (3)

Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither. Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass.

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

Example(s):

publicclassBar{// poor, missing a hashcode() methodpublicbooleanequals(Objecto){// do some comparison}}publicclassBaz{// poor, missing an equals() methodpublicinthashCode(){// return some hash value}}publicclassFoo{// perfect, both methods providedpublicbooleanequals(Objectother){// do some comparison}publicinthashCode(){// return some hash value}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/>

ProperCloneImplementation

Since: PMD 1.4

Priority: Medium High (2)

Object clone() should be implemented with super.clone().

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

Example(s):

classFoo{publicObjectclone(){returnnewFoo();// This is bad}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ProperCloneImplementation"/>

ProperLogger

Since: PMD 3.3

Priority: Medium (3)

A logger should normally be defined private static final and be associated with the correct class.private final Log log; is also allowed for rare cases where loggers need to be passed around,with the restriction that the logger needs to be passed into the constructor.

This rule is defined by the following XPath expression:

//FieldDeclaration[ClassType[pmd-java:typeIs($loggerClass)]][(: check modifiers :)(not(pmd-java:modifiers()='private')ornot(pmd-java:modifiers()='final'))(: check logger name :)or(pmd-java:modifiers()='static'andVariableDeclarator/VariableId/@Name!=$staticLoggerName)or(not(pmd-java:modifiers()='static')andVariableDeclarator/VariableId/@Name!=$loggerName)(: check logger argument type matches class or enum name :)or.//ArgumentList/ClassLiteral/ClassType/@SimpleName!=ancestor::ClassDeclaration/@SimpleNameor.//ArgumentList/ClassLiteral/ClassType/@SimpleName!=ancestor::EnumDeclaration/@SimpleName(: special case - final logger initialized inside constructor :)or(VariableDeclarator/@Initializer=false()andnot(pmd-java:modifiers()='static')andnot(ancestor::ClassBody/ConstructorDeclaration//AssignmentExpression[@Operator='='][FieldAccess[1]/@Name=$loggerNameorVariableAccess[1]/@Name=$loggerName][*[2][@Name=ancestor::ConstructorDeclaration//FormalParameter/VariableId/@Name]]))]

Example(s):

publicclassFoo{privatestaticfinalLogLOG=LogFactory.getLog(Foo.class);// proper wayprotectedLogLOG=LogFactory.getLog(Testclass.class);// wrong approach}

This rule has the following properties:

NameDefault ValueDescription
staticLoggerNameLOGName of the static Logger variable
loggerNamelogName of the Logger instance variable
loggerClassorg.apache.commons.logging.LogClass name of the logger

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

<ruleref="category/java/errorprone.xml/ProperLogger"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/ProperLogger"><properties><propertyname="staticLoggerName"value="LOG"/><propertyname="loggerName"value="log"/><propertyname="loggerClass"value="org.apache.commons.logging.Log"/></properties></rule>

ReturnEmptyCollectionRatherThanNull

Since: PMD 6.37.0

Priority: High (1)

For any method that returns an collection (such as an array, Collection or Map), it is better to returnan empty one rather than a null reference. This removes the need for null checking all results and avoidsinadvertent NullPointerExceptions.

See Effective Java, 3rd Edition, Item 54: Return empty collections or arrays instead of null

This rule is defined by the following XPath expression:

//ReturnStatement/NullLiteral[ancestor::MethodDeclaration[1][ArrayTypeorClassType[pmd-java:typeIs('java.util.Collection')orpmd-java:typeIs('java.util.Map')]]][not(./ancestor::LambdaExpression)]

Example(s):

publicclassExample{// Not a good idea...publicint[]badBehavior(){// ...returnnull;}// Good behaviorpublicString[]bonnePratique(){//...returnnewString[0];}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull"/>

ReturnFromFinallyBlock

Since: PMD 1.05

Priority: Medium (3)

Avoid returning from a finally block, this can discard exceptions.

This rule is defined by the following XPath expression:

//FinallyClause//ReturnStatementexcept//FinallyClause//(MethodDeclaration|LambdaExpression)//ReturnStatement

Example(s):

publicclassBar{publicStringfoo(){try{thrownewException("My Exception");}catch(Exceptione){throwe;}finally{return"A. O. K.";// return not recommended here}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/ReturnFromFinallyBlock"/>

SimpleDateFormatNeedsLocale

Since: PMD 2.0

Priority: Medium (3)

Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriateformatting is used.

This rule is defined by the following XPath expression:

//ConstructorCall[pmd-java:typeIs('java.text.SimpleDateFormat')][ArgumentList/@Size=1]

Example(s):

publicclassFoo{// Should specify Locale.US (or whatever)privateSimpleDateFormatsdf=newSimpleDateFormat("pattern");}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale"/>

SingleMethodSingleton

Since: PMD 5.4

Priority: Medium High (2)

Some classes contain overloaded getInstance. The problem with overloaded getInstance methodsis that the instance created using the overloaded method is not cached and so,for each call and new objects will be created for every invocation.

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

Example(s):

publicclassSingleton{privatestaticSingletonsingleton=newSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnsingleton;}publicstaticSingletongetInstance(Objectobj){Singletonsingleton=(Singleton)obj;returnsingleton;//violation}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SingleMethodSingleton"/>

SingletonClassReturningNewInstance

Since: PMD 5.4

Priority: Medium High (2)

A singleton class should only ever have one instance. Failure to checkwhether an instance has already been created may result in multipleinstances being created.

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

Example(s):

classSingleton{privatestaticSingletoninstance=null;publicstaticSingletongetInstance(){synchronized(Singleton.class){returnnewSingleton();// this should be assigned to the field}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SingletonClassReturningNewInstance"/>

StaticEJBFieldShouldBeFinal

Since: PMD 4.1

Priority: Medium (3)

According to the J2EE specification, an EJB should not have any static fieldswith write access. However, static read-only fields are allowed. This ensures properbehavior especially when instances are distributed by the container on several JREs.

This rule is defined by the following XPath expression:

//ClassDeclaration[ImplementsList/ClassType[pmd-java:typeIs('javax.ejb.SessionBean')orpmd-java:typeIs('javax.ejb.EJBHome')orpmd-java:typeIs('javax.ejb.EJBLocalObject')orpmd-java:typeIs('javax.ejb.EJBLocalHome')orpmd-java:typeIs('javax.ejb.EJBObject')]]/ClassBody/FieldDeclaration[pmd-java:modifiers()='static'][not(pmd-java:modifiers()='final')]

Example(s):

publicclassSomeEJBextendsEJBObjectimplementsEJBLocalHome{privatestaticintCountA;// poor, field can be editedprivatestaticfinalintCountB;// preferred, read-only access}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal"/>

StringBufferInstantiationWithChar

Since: PMD 3.9

Priority: Medium Low (4)

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()      //  16new StringBuffer(6)     //  6new StringBuffer("hello world")  // 11 + 16 = 27new StringBuffer('A')   //  chr(A) = 65new StringBuffer("A")   //  1 + 16 = 17new StringBuilder()     //  16new StringBuilder(6)    //  6new StringBuilder("hello world")  // 11 + 16 = 27new StringBuilder('C')   //  chr(C) = 67new StringBuilder("A")   //  1 + 16 = 17

This rule is defined by the following XPath expression:

//ConstructorCall[ArgumentList/*[pmd-java:typeIsExactly('char')]][pmd-java:matchesSig('java.lang.StringBuilder#new(int)')orpmd-java:matchesSig('java.lang.StringBuffer#new(int)')]

Example(s):

// misleading instantiation, these buffers// are actually sized to 99 characters longStringBuffersb1=newStringBuffer('c');StringBuildersb2=newStringBuilder('c');// in these forms, just single characters are allocatedStringBuffersb3=newStringBuffer("c");StringBuildersb4=newStringBuilder("c");

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/StringBufferInstantiationWithChar"/>

SuspiciousEqualsMethodName

Since: PMD 2.0

Priority: Medium High (2)

The method name and parameter number are suspiciously close toObject.equals, which can denote anintention to override it. However, the method does not overrideObject.equals, but overloads it instead.OverloadingObject.equals method is confusing for other programmers, error-prone and hard to maintain,especially when using inheritance, because@Override annotations used in subclasses can provide a falsesense of security. For more information onObject.equals method, see Effective Java, 3rd Edition,Item 10: Obey the general contract when overriding equals.

This rule is defined by the following XPath expression:

//MethodDeclaration[@Name='equals'][(@Arity=1andnot(FormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')])ornot(PrimitiveType[@Kind='boolean']))or(@Arity=2andPrimitiveType[@Kind='boolean']andFormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')]andnot(pmd-java:hasAnnotation('java.lang.Override')))]|//MethodDeclaration[@Name='equal'][@Arity=1andFormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')]]

Example(s):

publicclassFoo{publicintequals(Objecto){// oops, this probably was supposed to be boolean equals}publicbooleanequals(Strings){// oops, this probably was supposed to be equals(Object)}publicbooleanequals(Objecto1,Objecto2){// oops, this probably was supposed to be equals(Object)}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SuspiciousEqualsMethodName"/>

SuspiciousHashcodeMethodName

Since: PMD 1.5

Priority: Medium (3)

The method name and return type are suspiciously close to hashCode(), which may denote an intentionto override the hashCode() method.

This rule is defined by the following XPath expression:

//MethodDeclaration[lower-case(@Name)='hashcode'and@Name!='hashCode'and@Arity=0andPrimitiveType[@Kind='int']]

Example(s):

publicclassFoo{publicinthashcode(){// oops, this probably was supposed to be 'hashCode'}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SuspiciousHashcodeMethodName"/>

SuspiciousOctalEscape

Since: PMD 1.5

Priority: Medium (3)

A suspicious octal escape sequence was found inside a String literal.The Java language specification (section 3.10.6) says an octalescape sequence inside a literal String shall consist of a backslashfollowed by:

OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit

Any octal escape sequence followed by non-octal digits can be confusing,e.g. "\038" is interpreted as the octal escape sequence "\03" followed bythe literal character "8".

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

Example(s):

publicvoidfoo(){// interpreted as octal 12, followed by character '8'System.out.println("suspicious: \128");}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/SuspiciousOctalEscape"/>

TestClassWithoutTestCases

Since: PMD 3.0

Priority: Medium (3)

Test classes typically end with the suffix "Test", "Tests" or "TestCase". Having a non-test class with that nameis not a good practice, since most people will assume it is a test case. Test classes have test methodsnamed "testXXX" (JUnit3) or use annotations (e.g.@Test).

The suffix can be configured using the propertytestClassPattern. To disable the detection of possible test classesby name, set this property to an empty string.

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

Example(s):

//Consider changing the name of the class if it is not a test//Consider adding test methods if it is a testpublicclassCarTest{publicstaticvoidmain(String[]args){// do something}// code}

This rule has the following properties:

NameDefault ValueDescription
testClassPattern^(?:.*\.)?Test[^\.]*$|^(?:.*\.)?.*Tests?$|^(?:.*\.)?.*TestCase$Test class name pattern to identify test classes by their fully qualified name. An empty pattern disables test class detection by name. Since PMD 6.51.0.

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

<ruleref="category/java/errorprone.xml/TestClassWithoutTestCases"/>

Use this rule and customize it:

<ruleref="category/java/errorprone.xml/TestClassWithoutTestCases"><properties><propertyname="testClassPattern"value="^(?:.*\.)?Test[^\.]*$|^(?:.*\.)?.*Tests?$|^(?:.*\.)?.*TestCase$"/></properties></rule>

UnconditionalIfStatement

Since: PMD 1.5

Priority: Medium (3)

Do not use "if" statements whose conditionals are always true or always false.

This rule is defined by the following XPath expression:

//IfStatement[BooleanLiteral[1]]

Example(s):

publicclassFoo{publicvoidclose(){if(true){// fixed conditional, not recommended// ...}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UnconditionalIfStatement"/>

UnnecessaryBooleanAssertion

Since: PMD 3.0

Priority: Medium (3)

A JUnit test assertion with a boolean literal is unnecessary since it always will evaluate to the same thing.Consider using flow control (in case ofassertTrue(false) or similar) or simply removingstatements likeassertTrue(true) andassertFalse(false). If you just want a test to halt after findingan error, use thefail() method and provide an indication message of why it did.

This rule is defined by the following XPath expression:

//ClassDeclaration[pmd-java:typeIs('junit.framework.TestCase')or.//Annotation[pmd-java:typeIs('org.junit.Test')orpmd-java:typeIs('org.junit.jupiter.api.Test')orpmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')orpmd-java:typeIs('org.junit.jupiter.api.TestFactory')orpmd-java:typeIs('org.junit.jupiter.api.TestTemplate')orpmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')]]//MethodCall[@MethodName=('assertTrue','assertFalse')][ArgumentList[BooleanLiteralorUnaryExpression[@Operator='!'][BooleanLiteral]]]

Example(s):

publicclassSimpleTestextendsTestCase{publicvoidtestX(){assertTrue(true);// serves no real purpose - remove it}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UnnecessaryBooleanAssertion"/>

UnnecessaryCaseChange

Since: PMD 3.3

Priority: Medium (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.errorprone.UnnecessaryCaseChangeRule

Example(s):

booleananswer1=buz.toUpperCase().equals("BAZ");// should be buz.equalsIgnoreCase("BAZ")booleananswer2=buz.toUpperCase().equalsIgnoreCase("BAZ");// another unnecessary toUpperCase()

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UnnecessaryCaseChange"/>

UnnecessaryConversionTemporary

Since: PMD 0.1

Priority: Medium (3)

Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methodson the wrapper classes instead.

This rule is defined by the following XPath expression:

//MethodCall[@MethodName='toString'][ConstructorCall[position()=1][pmd-java:typeIs('java.lang.Integer')orpmd-java:typeIs('java.lang.Long')orpmd-java:typeIs('java.lang.Float')orpmd-java:typeIs('java.lang.Byte')orpmd-java:typeIs('java.lang.Double')orpmd-java:typeIs('java.lang.Short')]]

Example(s):

publicStringconvert(intx){Stringfoo=newInteger(x).toString();// this wastes an objectreturnInteger.toString(x);// preferred approach}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UnnecessaryConversionTemporary"/>

UnusedNullCheckInEquals

Since: PMD 3.5

Priority: Medium (3)

After checking an object reference for null, you should invoke equals() on that object rather than passingit to another object’s equals() method.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator='&&']/MethodCall[pmd-java:matchesSig("java.lang.Object#equals(java.lang.Object)")][not(StringLiteral)][not(VariableAccess[@CompileTimeConstant=true()])][ArgumentList/VariableAccess/@Name=..//InfixExpression[@Operator='!='][NullLiteral]/VariableAccess/@Name]

Example(s):

publicclassTest{publicStringmethod1(){return"ok";}publicStringmethod2(){returnnull;}publicvoidmethod(Stringa){Stringb;// I don't know it method1() can be "null"// but I know "a" is not null..// I'd better write a.equals(method1())if(a!=null&&method1().equals(a)){// will trigger the rule//whatever}if(method1().equals(a)&&a!=null){// won't trigger the rule//whatever}if(a!=null&&method1().equals(b)){// won't trigger the rule//whatever}if(a!=null&&"LITERAL".equals(a)){// won't trigger the rule//whatever}if(a!=null&&!a.equals("go")){// won't trigger the rulea=method2();if(method1().equals(a)){//whatever}}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UnusedNullCheckInEquals"/>

UseCorrectExceptionLogging

Since: PMD 3.2

Priority: Medium (3)

To make sure the full stacktrace is printed out, use the logging statement with two arguments: a String and a Throwable.

This rule only applies toApache Commons Logging.

This rule is defined by the following XPath expression:

//CatchClause/Block//MethodCall[pmd-java:matchesSig('org.apache.commons.logging.Log#_(java.lang.Object)')][ArgumentList[not(MethodCall)]//VariableAccess/@Name=ancestor::CatchClause/CatchParameter/@Name]

Example(s):

publicclassMain{privatestaticfinalLog_LOG=LogFactory.getLog(Main.class);voidbar(){try{}catch(Exceptione){_LOG.error(e);//Wrong!}catch(OtherExceptionoe){_LOG.error(oe.getMessage(),oe);//Correct}}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UseCorrectExceptionLogging"/>

UseEqualsToCompareStrings

Since: PMD 4.1

Priority: Medium (3)

Using ‘==’ or ‘!=’ to compare strings is only reliable if the interned string (String#intern())is used on both sides.

Use theequals() method instead.

This rule is defined by the following XPath expression:

//InfixExpression[@Operator=('==','!=')][count(*[pmd-java:typeIsExactly('java.lang.String')])=2]

Example(s):

publicbooleantest(Strings){if(s=="one")returntrue;// unreliableif("two".equals(s))returntrue;// betterreturnfalse;}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UseEqualsToCompareStrings"/>

UselessOperationOnImmutable

Since: PMD 3.5

Priority: Medium (3)

An operation on an immutable object will not change the object itself since the result of the operation is a new object.Therefore, ignoring the result of such an operation is likely a mistake. The operation can probably be removed.

This rule recognizes the typesString,BigDecimal,BigInteger or any type fromjava.time.* as immutable.

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

Example(s):

importjava.math.*;classTest{voidmethod1(){BigDecimalbd=newBigDecimal(10);bd.add(newBigDecimal(5));// this will trigger the rule}voidmethod2(){BigDecimalbd=newBigDecimal(10);bd=bd.add(newBigDecimal(5));// this won't trigger the rule}}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UselessOperationOnImmutable"/>

UseLocaleWithCaseConversions

Since: PMD 2.0

Priority: Medium (3)

When doingString::toLowerCase()/toUpperCase() conversions, use an explicit locale argument to specify the casetransformation rules.

UsingString::toLowerCase() without arguments implicitly usesLocale::getDefault().The problem is that the default locale depends on the current JVM setup (and usually on the system in whichit is running). Using the system default may be exactly what you want (e.g. if you are manipulating stringsyou got through standard input), but it may as well not be the case (e.g. if you are getting the string overthe network or a file, and the encoding is well-defined and independent of the environment). In the latter case,using the default locale makes the case transformation brittle, as it may yield unexpected results on a machinewhose locale has other case translation rules. For example, in Turkish, the uppercase form ofi isİ (U+0130,not ASCII) and notI (U+0049) as in English.

The rule is intended toforce developers to think about locales when dealing with strings. By taking aconscious decision about the choice of locale at the time of writing, you reduce the risk of surprisingbehaviour down the line, and communicate your intent to future readers.

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.String#toLowerCase()")orpmd-java:matchesSig("java.lang.String#toUpperCase()")][not(MethodCall[@MethodName="toHexString"])]

Example(s):

// violation - implicitly system-dependent conversionif(x.toLowerCase().equals("list")){}// The above will not match "LIST" on a system with a Turkish locale.// It could be replaced withif(x.toLowerCase(Locale.US).equals("list")){}// or simplyif(x.equalsIgnoreCase("list")){}// ok - system independent conversionStringz=a.toLowerCase(Locale.ROOT);// ok - explicit system-dependent conversionStringz2=a.toLowerCase(Locale.getDefault());

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UseLocaleWithCaseConversions"/>

UseProperClassLoader

Since: PMD 3.7

Priority: Medium (3)

In J2EE, the getClassLoader() method might not work as expected. UseThread.currentThread().getContextClassLoader() instead.

This rule is defined by the following XPath expression:

//MethodCall[pmd-java:matchesSig("java.lang.Class#getClassLoader()")]

Example(s):

publicclassFoo{ClassLoadercl=Bar.class.getClassLoader();}

Use this rule by referencing it:

<ruleref="category/java/errorprone.xml/UseProperClassLoader"/>

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: Jun 27, 2025

PMD                logo


[8]ページ先頭

©2009-2025 Movatter.jp