content/gradle/config/pmd/category/java/bestpractices.xml

1651 lines
60 KiB
XML
Raw Normal View History

2019-08-08 15:31:56 +02:00
<?xml version="1.0"?>
<ruleset name="Best Practices"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Rules which enforce generally accepted best practices.
</description>
<rule name="AbstractClassWithoutAbstractMethod"
language="java"
since="3.0"
message="This abstract class does not have any abstract methods"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#abstractclasswithoutabstractmethod">
<description>
The abstract class does not contain any abstract methods. An abstract class suggests
an incomplete implementation, which is to be completed by subclasses implementing the
abstract methods. If the class is intended to be used as a base class only (not to be instantiated
directly) a protected constructor can be provided prevent direct instantiation.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration
[@Abstract='true'
and count( .//MethodDeclaration[@Abstract='true'] )=0 ]
[count(ImplementsList)=0]
[count(.//ExtendsList)=0]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public abstract class Foo {
void int method1() { ... }
void int method2() { ... }
// consider using abstract methods or removing
// the abstract modifier and adding protected constructors
}
]]>
</example>
</rule>
<rule name="AccessorClassGeneration"
language="java"
2019-08-08 15:31:56 +02:00
since="1.04"
maximumLanguageVersion="10"
message="Avoid instantiation through private constructors from outside of the constructor's class."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorClassGenerationRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessorclassgeneration">
<description>
Instantiation by way of private constructors from outside of the constructor's class often causes the
generation of an accessor. A factory method, or non-privatization of the constructor can eliminate this
situation. The generated class file is actually an interface. It gives the accessing class the ability
to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter.
This turns a private constructor effectively into one with package scope, and is challenging to discern.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Outer {
void method(){
Inner ic = new Inner();//Causes generation of accessor class
}
public class Inner {
private Inner(){}
}
}
]]>
</example>
</rule>
<rule name="AccessorMethodGeneration"
language="java"
since="5.5.4"
maximumLanguageVersion="10"
message="Avoid autogenerated methods to access private fields and methods of inner / outer classes"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorMethodGenerationRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessormethodgeneration">
<description>
When accessing a private field / method from another class, the Java compiler will generate a accessor methods
with package-private visibility. This adds overhead, and to the dex method count on Android. This situation can
be avoided by changing the visibility of the field / method from private to package-private.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class OuterClass {
private int counter;
/* package */ int id;
public class InnerClass {
InnerClass() {
OuterClass.this.counter++; // wrong accessor method will be generated
}
public int getOuterClassId() {
return OuterClass.this.id; // id is package-private, no accessor method needed
}
}
}
]]>
</example>
</rule>
<rule name="ArrayIsStoredDirectly"
language="java"
2019-08-08 15:31:56 +02:00
since="2.2"
message="The user-supplied array ''{0}'' is stored directly."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.ArrayIsStoredDirectlyRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#arrayisstoreddirectly">
<description>
Constructors and methods receiving arrays should clone objects and store the copy.
This prevents future changes from the user from affecting the original array.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private String [] x;
public void foo (String [] param) {
// Don't do this, make a copy of the array at least
this.x=param;
}
}
]]>
</example>
</rule>
<rule name="AvoidPrintStackTrace"
language="java"
since="3.2"
message="Avoid printStackTrace(); use a logger call instead."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidprintstacktrace">
<description>
Avoid printStackTrace(); use a logger call instead.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression
[PrimaryPrefix/Name[contains(@Image,'printStackTrace')]]
[PrimarySuffix[not(boolean(Arguments/ArgumentList/Expression))]]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
class Foo {
void bar() {
try {
// do something
} catch (Exception e) {
e.printStackTrace();
}
}
}
]]>
</example>
</rule>
<rule name="AvoidReassigningLoopVariables"
language="java"
2019-08-08 15:31:56 +02:00
since="6.11.0"
message="Avoid reassigning the loop control variable ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningLoopVariablesRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningloopvariables">
<description>
Reassigning loop variables can lead to hard-to-find bugs. Prevent or limit how these variables can be changed.
In foreach-loops, configured by the `foreachReassign` property:
- `deny`: Report any reassignment of the loop variable in the loop body. _This is the default._
- `allow`: Don't check the loop variable.
- `firstOnly`: Report any reassignments of the loop variable, except as the first statement in the loop body.
_This is useful if some kind of normalization or clean-up of the value before using is permitted, but any other change of the variable is not._
In for-loops, configured by the `forReassign` property:
- `deny`: Report any reassignment of the control variable in the loop body. _This is the default._
- `allow`: Don't check the control variable.
- `skip`: Report any reassignments of the control variable, except conditional increments/decrements (`++`, `--`, `+=`, `-=`).
_This prevents accidental reassignments or unconditional increments of the control variable._
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private void foo() {
for (String s : listOfStrings()) {
s = s.trim(); // OK, when foreachReassign is "firstOnly" or "allow"
doSomethingWith(s);
s = s.toUpper(); // OK, when foreachReassign is "allow"
doSomethingElseWith(s);
}
for (int i=0; i < 10; i++) {
if (check(i)) {
i++; // OK, when forReassign is "skip" or "allow"
}
i = 5; // OK, when forReassign is "allow"
doSomethingWith(i);
}
}
}
]]>
</example>
</rule>
<rule name="AvoidReassigningParameters"
language="java"
2019-08-08 15:31:56 +02:00
since="1.0"
message="Avoid reassigning parameters such as ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningParametersRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningparameters">
<description>
Reassigning values to incoming parameters is not recommended. Use temporary local variables instead.
</description>
<priority>2</priority>
<example>
<![CDATA[
public class Foo {
private void foo(String bar) {
bar = "something else";
}
}
]]>
</example>
</rule>
<rule name="AvoidStringBufferField"
language="java"
since="4.2"
message="StringBuffers can grow quite a lot, and so may become a source of memory leak (if the owning class has a long life time)."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidstringbufferfield">
<description>
StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks
if held within objects with long lifetimes.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//FieldDeclaration/Type/ReferenceType/ClassOrInterfaceType[@Image = 'StringBuffer' or @Image = 'StringBuilder']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
private StringBuffer buffer; // potential memory leak as an instance variable;
}
]]>
</example>
</rule>
<rule name="AvoidUsingHardCodedIP"
language="java"
2019-08-08 15:31:56 +02:00
since="4.1"
message="Do not hard code the IP address ${variableName}"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidUsingHardCodedIPRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidusinghardcodedip">
<description>
Application with hard-coded IP addresses can become impossible to deploy in some cases.
Externalizing IP adresses is preferable.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private String ip = "127.0.0.1"; // not recommended
}
]]>
</example>
</rule>
<rule name="CheckResultSet"
language="java"
since="4.1"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.CheckResultSetRule"
message="Always check the return of one of the navigation method (next,previous,first,last) of a ResultSet."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#checkresultset">
<description>
Always check the return values of navigation methods (next, previous, first, last) of a ResultSet.
If the value return is 'false', it should be handled properly.
</description>
<priority>3</priority>
<example>
<![CDATA[
Statement stat = conn.createStatement();
ResultSet rst = stat.executeQuery("SELECT name FROM person");
rst.next(); // what if it returns false? bad form
String firstName = rst.getString(1);
Statement stat = conn.createStatement();
ResultSet rst = stat.executeQuery("SELECT name FROM person");
if (rst.next()) { // result is properly examined and used
String firstName = rst.getString(1);
} else {
// handle missing data
}
]]>
</example>
</rule>
<rule name="ConstantsInInterface"
language="java"
since="5.5"
message="Avoid constants in interfaces. Interfaces define types, constants are implementation details better placed in classes or enums. See Effective Java, item 19."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#constantsininterface">
<description>
Avoid constants in interfaces. Interfaces should define types, constants are implementation details
better placed in classes or enums. See Effective Java, item 19.
</description>
<priority>3</priority>
<properties>
<property name="ignoreIfHasMethods" type="Boolean" description="Whether to ignore constants in interfaces if the interface defines any methods" value="true"/>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[@Interface='true'][$ignoreIfHasMethods='false' or not(.//MethodDeclaration)]//FieldDeclaration
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public interface ConstantInterface {
public static final int CONST1 = 1; // violation, no fields allowed in interface!
static final int CONST2 = 1; // violation, no fields allowed in interface!
final int CONST3 = 1; // violation, no fields allowed in interface!
int CONST4 = 1; // violation, no fields allowed in interface!
}
// with ignoreIfHasMethods = false
public interface AnotherConstantInterface {
public static final int CONST1 = 1; // violation, no fields allowed in interface!
int anyMethod();
}
// with ignoreIfHasMethods = true
public interface YetAnotherConstantInterface {
public static final int CONST1 = 1; // no violation
int anyMethod();
}
]]>
</example>
</rule>
<rule name="DefaultLabelNotLastInSwitchStmt"
language="java"
since="1.5"
message="The default label should be the last label in a switch statement"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#defaultlabelnotlastinswitchstmt">
<description>
By convention, the default label should be the last label in a switch statement.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//SwitchStatement
[not(SwitchLabel[position() = last()][@Default='true'])]
[SwitchLabel[@Default='true']]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
void bar(int a) {
switch (a) {
case 1: // do something
break;
default: // the default case should be last, by convention
break;
case 2:
break;
}
}
}
]]>
</example>
</rule>
<rule name="ForLoopCanBeForeach"
language="java"
since="6.0.0"
message="This 'for' loop can be replaced by a 'foreach' loop"
typeResolution="true"
minimumLanguageVersion="1.5"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.ForLoopCanBeForeachRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#forloopcanbeforeach">
<description>
Reports loops that can be safely replaced with the foreach syntax. The rule considers loops over
lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to
access an element of the list or array, only has one update statement, and loops through *every*
element of the list or array left to right.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class MyClass {
void loop(List<String> l) {
for (int i = 0; i < l.size(); i++) { // pre Java 1.5
System.out.println(l.get(i));
}
for (String s : l) { // post Java 1.5
System.out.println(s);
}
}
}
]]>
</example>
</rule>
<rule name="ForLoopVariableCount"
language="java"
since="6.11.0"
message="Too many control variables in the 'for' statement"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#forloopvariablecount">
<description>
Having a lot of control variables in a 'for' loop makes it harder to see what range of values
the loop iterates over. By default this rule allows a regular 'for' loop with only one variable.
</description>
<priority>3</priority>
<properties>
<property name="maximumVariables" type="Integer"
description="A regular for statement will have 1 control variable" min="0" max="100" value="1"/>
<property name="xpath">
<value>//ForInit/LocalVariableDeclaration[count(VariableDeclarator) > $maximumVariables]</value>
</property>
</properties>
<example>
<![CDATA[
// this will be reported with the default setting of at most one control variable in a for loop
for (int i = 0, j = 0; i < 10; i++, j += 2) {
foo();
]]>
</example>
</rule>
<rule name="GuardLogStatement"
language="java"
since="5.1.0"
message="Logger calls should be surrounded by log level guards."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.GuardLogStatementRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#guardlogstatement">
<description>
Whenever using a log level, one should check if the loglevel is actually enabled, or
otherwise skip the associate String creation and manipulation.
</description>
<priority>2</priority>
<example>
<![CDATA[
// Add this for performance
if (log.isDebugEnabled() { ...
log.debug("log something" + " and " + "concat strings");
]]>
</example>
</rule>
<rule name="JUnit4SuitesShouldUseSuiteAnnotation"
language="java"
since="4.0"
message="JUnit 4 indicates test suites via annotations, not the suite method."
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4suitesshouldusesuiteannotation">
<description>
In JUnit 3, test suites are indicated by the suite() method. In JUnit 4, suites are indicated
through the @RunWith(Suite.class) annotation.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceBodyDeclaration[MethodDeclaration/MethodDeclarator[@Name='suite']]
2019-08-08 15:31:56 +02:00
[MethodDeclaration/ResultType/Type/ReferenceType/ClassOrInterfaceType[pmd-java:typeIs('junit.framework.Test')]]
[not(MethodDeclaration/Block//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.JUnit4TestAdapter')])]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class BadExample extends TestCase{
public static Test suite(){
return new Suite();
}
}
@RunWith(Suite.class)
@SuiteClasses( { TestOne.class, TestTwo.class })
public class GoodTest {
}
]]>
</example>
</rule>
<rule name="JUnit4TestShouldUseAfterAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that clean up tests should use the @After annotation, JUnit5 tests should use @AfterEach or @AfterAll"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshoulduseafterannotation">
<description>
In JUnit 3, the tearDown method was used to clean up all data entities required in running tests.
JUnit 4 skips the tearDown method and executes all methods annotated with @After after running each test.
JUnit 5 introduced @AfterEach and @AfterAll annotations to execute methods after each test or after all tests in the class, respectively.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceBodyDeclaration
[MethodDeclaration/MethodDeclarator[@Name='tearDown']]
2019-08-08 15:31:56 +02:00
[count(Annotation//Name[
pmd-java:typeIs('org.junit.After')
or pmd-java:typeIs('org.junit.jupiter.api.AfterEach')
or pmd-java:typeIs('org.junit.jupiter.api.AfterAll')
or pmd-java:typeIs('org.testng.annotations.AfterMethod')])=0]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class MyTest {
public void tearDown() {
bad();
}
}
public class MyTest2 {
@After public void tearDown() {
good();
}
}
]]>
</example>
</rule>
<rule name="JUnit4TestShouldUseBeforeAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that set up tests should use the @Before annotation, JUnit5 tests should use @BeforeEach or @BeforeAll"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusebeforeannotation">
<description>
In JUnit 3, the setUp method was used to set up all data entities required in running tests.
JUnit 4 skips the setUp method and executes all methods annotated with @Before before all tests.
JUnit 5 introduced @BeforeEach and @BeforeAll annotations to execute methods before each test or before all tests in the class, respectively.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceBodyDeclaration
[MethodDeclaration/MethodDeclarator[@Name='setUp']]
2019-08-08 15:31:56 +02:00
[count(Annotation//Name[
pmd-java:typeIs('org.junit.Before')
or pmd-java:typeIs('org.junit.jupiter.api.BeforeEach')
or pmd-java:typeIs('org.junit.jupiter.api.BeforeAll')
or pmd-java:typeIs('org.testng.annotations.BeforeMethod')])=0]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class MyTest {
public void setUp() {
bad();
}
}
public class MyTest2 {
@Before public void setUp() {
good();
}
}
]]>
</example>
</rule>
<rule name="JUnit4TestShouldUseTestAnnotation"
language="java"
since="4.0"
message="JUnit 4 tests that execute tests should use the @Test annotation, JUnit 5 tests should use @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4testshouldusetestannotation">
<description>
In JUnit 3, the framework executed all methods which started with the word test as a unit test.
In JUnit 4, only methods annotated with the @Test annotation are executed.
In JUnit 5, one of the following annotations should be used for tests: @Test, @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[
matches(@SimpleName, $testClassPattern)
2019-08-08 15:31:56 +02:00
or ExtendsList/ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]]
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration[MethodDeclaration[@Public=true()]/MethodDeclarator[starts-with(@Name, 'test')]]
2019-08-08 15:31:56 +02:00
[not(Annotation//Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
])]
]]>
</value>
</property>
<property name="testClassPattern" type="Regex" description="The regex pattern used to identify test classes" value="Test" />
<property name="version" value="2.0"/>
</properties>
<example>
<![CDATA[
public class MyTest {
public void testBad() {
doSomething();
}
@Test
public void testGood() {
doSomething();
}
}
]]>
</example>
</rule>
<rule name="JUnitAssertionsShouldIncludeMessage"
language="java"
2019-08-08 15:31:56 +02:00
since="1.04"
message="JUnit assertions should include a message"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitAssertionsShouldIncludeMessageRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junitassertionsshouldincludemessage">
<description>
JUnit assertions should include an informative message - i.e., use the three-argument version of
assertEquals(), not the two-argument version.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo extends TestCase {
public void testSomething() {
assertEquals("foo", "bar");
// Use the form:
// assertEquals("Foo does not equals bar", "foo", "bar");
// instead
}
}
]]>
</example>
</rule>
<rule name="JUnitTestContainsTooManyAsserts"
language="java"
since="5.0"
message="Unit tests should not contain more than ${maximumAsserts} assert(s)."
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestcontainstoomanyasserts">
<description>
Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which
it is harder to verify correctness. Consider breaking the test scenario into multiple, shorter test scenarios.
Customize the maximum number of assertions used by this Rule to suit your needs.
This rule checks for JUnit4, JUnit5 and TestNG Tests, as well as methods starting with "test".
</description>
<priority>3</priority>
<properties>
<property name="maximumAsserts" type="Integer" min="1" max="1000" description="Maximum number of Asserts in a test method" value="1"/>
<property name="xpath">
<value>
<![CDATA[
//MethodDeclarator[@Image[fn:matches(.,'^test')] or ../../Annotation/MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test')
or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
or pmd-java:typeIs('org.testng.annotations.Test')
]]
[count(..//PrimaryPrefix/Name[@Image[fn:matches(.,'^assert')]]) > $maximumAsserts]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class MyTestCase extends TestCase {
// Ok
public void testMyCaseWithOneAssert() {
boolean myVar = false;
assertFalse("should be false", myVar);
}
// Bad, too many asserts (assuming max=1)
public void testMyCaseWithMoreAsserts() {
boolean myVar = false;
assertFalse("myVar should be false", myVar);
assertEquals("should equals false", false, myVar);
}
}
]]>
</example>
</rule>
<rule name="JUnitTestsShouldIncludeAssert"
language="java"
2019-08-08 15:31:56 +02:00
since="2.0"
message="JUnit tests should include assert() or fail()"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitTestsShouldIncludeAssertRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junittestsshouldincludeassert">
<description>
JUnit tests should include at least one assertion. This makes the tests more robust, and using assert
with messages provide the developer a clearer idea of what the test does.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo extends TestCase {
public void testSomething() {
Bar b = findBar();
// This is better than having a NullPointerException
// assertNotNull("bar not found", b);
b.work();
}
}
]]>
</example>
</rule>
<rule name="JUnitUseExpected"
language="java"
2019-08-08 15:31:56 +02:00
since="4.0"
message="In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitUseExpectedRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junituseexpected">
<description>
In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class MyTest {
@Test
public void testBad() {
try {
doSomething();
fail("should have thrown an exception");
} catch (Exception e) {
}
}
@Test(expected=Exception.class)
public void testGood() {
doSomething();
}
}
]]>
</example>
</rule>
<rule name="LooseCoupling"
language="java"
2019-08-08 15:31:56 +02:00
since="0.7"
message="Avoid using implementation types like ''{0}''; use the interface instead"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.LooseCouplingRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#loosecoupling">
<description>
The use of implementation types (i.e., HashSet) as object references limits your ability to use alternate
implementations in the future as requirements change. Whenever available, referencing objects
by their interface types (i.e, Set) provides much more flexibility.
</description>
<priority>3</priority>
<example>
<![CDATA[
import java.util.ArrayList;
import java.util.HashSet;
public class Bar {
// sub-optimal approach
private ArrayList<SomeType> list = new ArrayList<>();
public HashSet<SomeType> getFoo() {
return new HashSet<SomeType>();
}
// preferred approach
private List<SomeType> list = new ArrayList<>();
public Set<SomeType> getFoo() {
return new HashSet<SomeType>();
}
}
]]>
</example>
</rule>
<rule name="MethodReturnsInternalArray"
language="java"
2019-08-08 15:31:56 +02:00
since="2.2"
message="Returning ''{0}'' may expose an internal array."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.MethodReturnsInternalArrayRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#methodreturnsinternalarray">
<description>
Exposing internal arrays to the caller violates object encapsulation since elements can be
removed or replaced outside of the object that owns it. It is safer to return a copy of the array.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class SecureSystem {
UserData [] ud;
public UserData [] getUserData() {
// Don't return directly the internal array, return a copy
return ud;
}
}
]]>
</example>
</rule>
<rule name="MissingOverride"
language="java"
2019-08-08 15:31:56 +02:00
since="6.2.0"
minimumLanguageVersion="1.5"
message="The method ''{0}'' is missing an @Override annotation."
typeResolution="true"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.MissingOverrideRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#missingoverride">
<description>
Annotating overridden methods with @Override ensures at compile time that
the method really overrides one, which helps refactoring and clarifies intent.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo implements Runnable {
// This method is overridden, and should have an @Override annotation
public void run() {
}
}
]]>
</example>
</rule>
<rule name="OneDeclarationPerLine"
language="java"
since="5.0"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="Use one line for each declaration, it enhances code readability."
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#onedeclarationperline">
<description>
Java allows the use of several variables declaration of the same type on one line. However, it
can lead to quite messy code. This rule looks for several declarations on the same line.
</description>
<priority>4</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//LocalVariableDeclaration
[not(parent::ForInit)]
[count(VariableDeclarator) > 1]
[$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
|
//FieldDeclaration
[count(VariableDeclarator) > 1]
[$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
]]>
</value>
</property>
<property name="version" value="2.0"/>
<property name="strictMode" type="Boolean" value="false"
description="If true, mark combined declaration even if the declarations are on separate lines."/>
</properties>
<example>
<![CDATA[
String name; // separate declarations
String lastname;
String name, lastname; // combined declaration, a violation
String name,
lastname; // combined declaration on multiple lines, no violation by default.
// Set property strictMode to true to mark this as violation.
]]>
</example>
</rule>
<rule name="PositionLiteralsFirstInCaseInsensitiveComparisons"
language="java"
since="5.1"
message="Position literals first in String comparisons for EqualsIgnoreCase"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#positionliteralsfirstincaseinsensitivecomparisons">
<description>
Position literals first in comparisons, if the second argument is null then NullPointerExceptions
can be avoided, they will just return false.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[
PrimaryPrefix[Name
[
(ends-with(@Image, '.equalsIgnoreCase'))
]
]
[
(../PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal)
and
( count(../PrimarySuffix/Arguments/ArgumentList/Expression) = 1 )
]
]
[not(ancestor::Expression/ConditionalAndExpression//EqualityExpression[@Image='!=']//NullLiteral)]
[not(ancestor::Expression/ConditionalOrExpression//EqualityExpression[@Image='==']//NullLiteral)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
class Foo {
boolean bar(String x) {
return x.equalsIgnoreCase("2"); // should be "2".equalsIgnoreCase(x)
}
}
]]>
</example>
</rule>
<rule name="PositionLiteralsFirstInComparisons"
language="java"
since="3.3"
message="Position literals first in String comparisons"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#positionliteralsfirstincomparisons">
<description>
Position literals first in comparisons, if the second argument is null then NullPointerExceptions
can be avoided, they will just return false.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[
PrimaryPrefix[Name[(ends-with(@Image, '.equals'))]]
[
(../PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal[@StringLiteral='true'])
and
( count(../PrimarySuffix/Arguments/ArgumentList/Expression) = 1 )
]
]
[not(ancestor::Expression/ConditionalAndExpression//EqualityExpression[@Image='!=']//NullLiteral)]
[not(ancestor::Expression/ConditionalOrExpression//EqualityExpression[@Image='==']//NullLiteral)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
class Foo {
boolean bar(String x) {
return x.equals("2"); // should be "2".equals(x)
}
}
]]>
</example>
</rule>
<rule name="PreserveStackTrace"
language="java"
2019-08-08 15:31:56 +02:00
since="3.7"
message="New exception is thrown in catch block, original stack trace may be lost"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.PreserveStackTraceRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#preservestacktrace">
<description>
Throwing a new exception from a catch block without passing the original exception into the
new exception will cause the original stack trace to be lost making it difficult to debug
effectively.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
try{
Integer.parseInt("a");
} catch (Exception e) {
throw new Exception(e); // first possibility to create exception chain
}
try {
Integer.parseInt("a");
} catch (Exception e) {
throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
}
}
void bad() {
try{
Integer.parseInt("a");
} catch (Exception e) {
throw new Exception(e.getMessage());
}
}
}
]]>
</example>
</rule>
<rule name="ReplaceEnumerationWithIterator"
language="java"
since="3.4"
message="Consider replacing this Enumeration with the newer java.util.Iterator"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replaceenumerationwithiterator">
<description>
Consider replacing Enumeration usages with the newer java.util.Iterator
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ImplementsList/ClassOrInterfaceType[@Image='Enumeration']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo implements Enumeration {
private int x = 42;
public boolean hasMoreElements() {
return true;
}
public Object nextElement() {
return String.valueOf(i++);
}
}
]]>
</example>
</rule>
<rule name="ReplaceHashtableWithMap"
language="java"
since="3.4"
message="Consider replacing this Hashtable with the newer java.util.Map"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacehashtablewithmap">
<description>
Consider replacing Hashtable usage with the newer java.util.Map if thread safety is not required.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//Type/ReferenceType/ClassOrInterfaceType[@Image='Hashtable']</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
void bar() {
Hashtable h = new Hashtable();
}
}
]]>
</example>
</rule>
<rule name="ReplaceVectorWithList"
language="java"
since="3.4"
message="Consider replacing this Vector with the newer java.util.List"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacevectorwithlist">
<description>
Consider replacing Vector usages with the newer java.util.ArrayList if expensive thread-safe operations are not required.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>//Type/ReferenceType/ClassOrInterfaceType[@Image='Vector']</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
void bar() {
Vector v = new Vector();
}
}
]]>
</example>
</rule>
<rule name="SwitchStmtsShouldHaveDefault"
language="java"
since="1.0"
message="Switch statements should have a default label"
typeResolution="true"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#switchstmtsshouldhavedefault">
<description>
All switch statements should include a default option to catch any unspecified values.
</description>
<priority>3</priority>
<properties>
<property name="version" value="2.0"/>
<property name="xpath">
<value><![CDATA[
//SwitchStatement[@DefaultCase = false() and @ExhaustiveEnumSwitch = false()]
]]></value>
</property>
</properties>
<example>
<![CDATA[
public void bar() {
int x = 2;
switch (x) {
case 1: int j = 6;
case 2: int j = 8;
// missing default: here
}
}
]]>
</example>
</rule>
<rule name="SystemPrintln"
language="java"
since="2.1"
message="{0} is used"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#systemprintln">
<description>
References to System.(out|err).print are usually intended for debugging purposes and can remain in
the codebase even in production code. By using a logger one can enable/disable this behaviour at
will (and by priority) and avoid clogging the Standard out log.
</description>
<priority>2</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//Name[
starts-with(@Image, 'System.out.print')
or
starts-with(@Image, 'System.err.print')
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
class Foo{
Logger log = Logger.getLogger(Foo.class.getName());
public void testA () {
System.out.println("Entering test");
// Better use this
log.fine("Entering test");
}
}
]]>
</example>
</rule>
<rule name="UnusedFormalParameter"
language="java"
since="0.8"
message="Avoid unused {0} parameters such as ''{1}''."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedFormalParameterRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedformalparameter">
<description>
Avoid passing parameters to methods or constructors without actually referencing them in the method body.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
private void bar(String howdy) {
// howdy is not used
}
}
]]>
</example>
</rule>
<rule name="UnusedImports"
language="java"
2019-08-08 15:31:56 +02:00
since="1.0"
message="Avoid unused imports such as ''{0}''"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedImportsRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedimports">
<description>
Avoid unused import statements to prevent unwanted dependencies.
This rule will also find unused on demand imports, i.e. import com.foo.*.
</description>
<priority>4</priority>
<example>
<![CDATA[
import java.io.File; // not referenced or required
import java.util.*; // not referenced or required
public class Foo {}
]]>
</example>
</rule>
<rule name="UnusedLocalVariable"
language="java"
since="0.1"
message="Avoid unused local variables such as ''{0}''."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedLocalVariableRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedlocalvariable">
<description>
Detects when a local variable is declared and/or assigned, but not used.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
public void doSomething() {
int i = 5; // Unused
}
}
]]>
</example>
</rule>
<rule name="UnusedPrivateField"
since="0.1"
language="java"
message="Avoid unused private fields such as ''{0}''."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateFieldRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatefield">
<description>
Detects when a private field is declared and/or assigned a value, but not used.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Something {
private static int FOO = 2; // Unused
private int i = 5; // Unused
private int j = 6;
public int addOne() {
return j++;
}
}
]]>
</example>
</rule>
<rule name="UnusedPrivateMethod"
language="java"
since="0.7"
message="Avoid unused private methods such as ''{0}''."
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateMethodRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatemethod">
<description>
Unused Private Method detects when a private method is declared but is unused.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Something {
private void foo() {} // unused
}
]]>
</example>
</rule>
<rule name="UseAssertEqualsInsteadOfAssertTrue"
language="java"
since="3.1"
message="Use assertEquals(x, y) instead of assertTrue(x.equals(y))"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertequalsinsteadofasserttrue">
<description>
This rule detects JUnit assertions in object equality. These assertions should be made by more specific methods, like assertEquals.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[
PrimaryPrefix/Name[@Image = 'assertTrue']
][
PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Name
[ends-with(@Image, '.equals')]
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class FooTest extends TestCase {
void testCode() {
Object a, b;
assertTrue(a.equals(b)); // bad usage
assertEquals(?a should equals b?, a, b); // good usage
}
}
]]>
</example>
</rule>
<rule name="UseAssertNullInsteadOfAssertTrue"
language="java"
since="3.5"
message="Use assertNull(x) instead of assertTrue(x==null), or assertNotNull(x) vs assertFalse(x==null)"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertnullinsteadofasserttrue">
<description>
This rule detects JUnit assertions in object references equality. These assertions should be made by
more specific methods, like assertNull, assertNotNull.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[
PrimaryPrefix/Name[@Image = 'assertTrue' or @Image = 'assertFalse']
][
PrimarySuffix/Arguments/ArgumentList[
Expression/EqualityExpression/PrimaryExpression/PrimaryPrefix/Literal/NullLiteral
]
]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class FooTest extends TestCase {
void testCode() {
Object a = doSomething();
assertTrue(a==null); // bad usage
assertNull(a); // good usage
assertTrue(a != null); // bad usage
assertNotNull(a); // good usage
}
}
]]>
</example>
</rule>
<rule name="UseAssertSameInsteadOfAssertTrue"
language="java"
since="3.1"
message="Use assertSame(x, y) instead of assertTrue(x==y), or assertNotSame(x,y) vs assertFalse(x==y)"
class="net.sourceforge.pmd.lang.rule.XPathRule"
typeResolution="true"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useassertsameinsteadofasserttrue">
<description>
This rule detects JUnit assertions in object references equality. These assertions should be made
by more specific methods, like assertSame, assertNotSame.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[
PrimaryPrefix/Name
[@Image = 'assertTrue' or @Image = 'assertFalse']
]
[PrimarySuffix/Arguments
/ArgumentList/Expression
/EqualityExpression[count(.//NullLiteral) = 0]]
[ancestor::ClassOrInterfaceDeclaration[//ClassOrInterfaceType[pmd-java:typeIs('junit.framework.TestCase')]
or //MarkerAnnotation/Name[
pmd-java:typeIs('org.junit.Test')
or pmd-java:typeIs('org.junit.jupiter.api.Test') or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
or pmd-java:typeIs('org.junit.jupiter.api.TestFactory') or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
]
]]]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class FooTest extends TestCase {
void testCode() {
Object a, b;
assertTrue(a == b); // bad usage
assertSame(a, b); // good usage
}
}
]]>
</example>
</rule>
<rule name="UseAssertTrueInsteadOfAssertEquals"
language="java"
since="5.0"
message="Use assertTrue(x)/assertFalse(x) instead of assertEquals(true, x)/assertEquals(false, x) or assertEquals(Boolean.TRUE, x)/assertEquals(Boolean.FALSE, x)."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useasserttrueinsteadofassertequals">
<description>
When asserting a value is the same as a literal or Boxed boolean, use assertTrue/assertFalse, instead of assertEquals.
</description>
<priority>3</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//PrimaryExpression[PrimaryPrefix/Name[@Image = 'assertEquals']]
[
PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral
or
PrimarySuffix/Arguments/ArgumentList/Expression/PrimaryExpression/PrimaryPrefix
/Name[(@Image = 'Boolean.TRUE' or @Image = 'Boolean.FALSE')]
]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class MyTestCase extends TestCase {
public void testMyCase() {
boolean myVar = true;
// Ok
assertTrue("myVar is true", myVar);
// Bad
assertEquals("myVar is true", true, myVar);
// Bad
assertEquals("myVar is false", false, myVar);
// Bad
assertEquals("myVar is true", Boolean.TRUE, myVar);
// Bad
assertEquals("myVar is false", Boolean.FALSE, myVar);
}
}
]]>
</example>
</rule>
<rule name="UseCollectionIsEmpty"
language="java"
2019-08-08 15:31:56 +02:00
since="3.9"
message="Substitute calls to size() == 0 (or size() != 0, size() &gt; 0, size() &lt; 1) with calls to isEmpty()"
class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseCollectionIsEmptyRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usecollectionisempty">
<description>
The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements.
Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method.
</description>
<priority>3</priority>
<example>
<![CDATA[
public class Foo {
void good() {
List foo = getList();
if (foo.isEmpty()) {
// blah
}
}
void bad() {
List foo = getList();
if (foo.size() == 0) {
// blah
}
}
}
]]>
</example>
</rule>
<rule name="UseTryWithResources"
language="java"
minimumLanguageVersion="1.7"
since="6.12.0"
typeResolution="true"
message="Consider using a try-with-resources statement instead of explicitly closing the resource"
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usetrywithresources">
<description>
Java 7 introduced the try-with-resources statement. This statement ensures that each resource is closed at the end
of the statement. It avoids the need of explicitly closing the resources in a finally block. Additionally exceptions
are better handled: If an exception occurred both in the `try` block and `finally` block, then the exception from
the try block was suppressed. With the `try`-with-resources statement, the exception thrown from the try-block is
preserved.
</description>
<priority>3</priority>
<properties>
<property name="closeMethods" type="List[String]" delimiter="," description="Method names in finally block, which trigger this rule" value="close,closeQuietly"/>
<property name="version" value="2.0" />
<property name="xpath">
<value>
<![CDATA[
//TryStatement[FinallyStatement//Name[
tokenize(@Image, '\.')[last()] = $closeMethods
][
pmd-java:typeIs('java.lang.AutoCloseable')
or
../../PrimarySuffix/Arguments[@Size = 1]//PrimaryPrefix[pmd-java:typeIs('java.lang.AutoCloseable')]
2019-08-08 15:31:56 +02:00
]]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class TryWithResources {
public void run() {
InputStream in = null;
try {
in = openInputStream();
int i = in.read();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) in.close();
} catch (IOException ignored) {
// ignored
}
}
// better use try-with-resources
try (InputStream in2 = openInputStream()) {
int i = in2.read();
}
}
}
]]>
</example>
</rule>
<rule name="UseVarargs"
language="java"
minimumLanguageVersion="1.5"
since="5.0"
message="Consider using varargs for methods or constructors which take an array the last parameter."
class="net.sourceforge.pmd.lang.rule.XPathRule"
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usevarargs">
<description>
Java 5 introduced the varargs parameter declaration for methods and constructors. This syntactic
sugar provides flexibility for users of these methods and constructors, allowing them to avoid
having to deal with the creation of an array.
</description>
<priority>4</priority>
<properties>
<property name="version" value="2.0" />
<property name="xpath">
<value>
<![CDATA[
//FormalParameters/FormalParameter
[position()=last()]
[VariableDeclaratorId/@ArrayType=true()]
[@Varargs=false()]
[not (./Type[@ArrayType=true()]/ReferenceType[PrimitiveType[@Image='byte']])]
[not (./Type/ReferenceType[ClassOrInterfaceType[@Image='Byte']])]
[not (./Type/PrimitiveType[@Image='byte'])]
[not (ancestor::MethodDeclaration/preceding-sibling::Annotation/*/Name[@Image='Override'])]
[not(
ancestor::MethodDeclaration
[@Public=true() and @Static=true()]
[child::ResultType[@Void=true()]] and
ancestor::MethodDeclarator[@Image='main'] and
..[@ParameterCount=1] and
./Type/ReferenceType[ClassOrInterfaceType[@Image='String']]
)]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
public void foo(String s, Object[] args) {
// Do something here...
}
public void bar(String s, Object... args) {
// Ahh, varargs tastes much better...
}
}
]]>
</example>
</rule>
</ruleset>