PMD 기본 규칙

잡동사니

PMD
앤트 작업
규칙
기본 규칙

http://pmd.sourceforge.net/rules/basic.html

기본 규칙은 대부분의 개발에서 실질적으로 쓰일만한 것을 포함하고 있다.

목차

빈 예외잡기 블럭 (EmptyCatchBlock)

http://pmd.sourceforge.net/rules/basic.html#EmptyCatchBlock

도입
PMD 0.1

이 규칙은 예외를 잡긴 잡으나(catch) 아무것도 하지 않는 블럭을 탐지한다. 이런 블럭은 예외가 보고되야 하든지, 아니면 무시하고 그 뒤 코드가 실행되야 하든지 간에 예외를 무조건 삼켜버리는 코드다.

XPath 표현식
//CatchStatement
 [count(Block/BlockStatement) = 0 and ($allowCommentedBlocks != 'true' or Block/@containsComment = 'false')]
 [FormalParameter/Type/ReferenceType
   /ClassOrInterfaceType[@Image != 'InterruptedException' and @Image != 'CloneNotSupportedException']
 ]
예제
public void doSomething() {
  try {
    FileInputStream fis = new FileInputStream("/tmp/bugger");
  } catch (IOException ioe) {
      // not good
  }
}
속성
이름 기본값 설명
allowCommentedBlocks 주석이 있는 빈 블럭은 넘어간다.

빈 조건문 (EmptyIfStmt)

http://pmd.sourceforge.net/rules/basic.html#EmptyIfStmt

도입
PMD 0.1

이 규칙은 비어 있는 조건문을 탐지한다.

XPath 표현식
//IfStatement/Statement
 [EmptyStatement or Block[count(*) = 0]]
예제
public class Foo {
 void bar(int x) {
  if (x == 0) {
   // empty!
  }
 }
}

빈 반복문 (EmptyWhileStmt)

http://pmd.sourceforge.net/rules/basic.html#EmptyWhileStmt

도입
PMD 0.2

이 규칙은 비어 있는 반복문을 탐지한다. 만일 시간제한 반복문을 사용하려면 Thread.sleep() 메서드를 사용하라. if it's a while loop that does a lot in the exit expression, rewrite it to make it clearer.

XPath 표현식
//WhileStatement/Statement[./Block[count(*) = 0]  or ./EmptyStatement]
예제


public class Foo {
 void bar(int a, int b) {
  while (a == b) {
   // empty!
  }
 }
}

빈 시도문 (EmptyTryBlock)

http://pmd.sourceforge.net/rules/basic.html#EmptyTryBlock

도입
PMD 0.4

이 규칙은 빈 시도문(try)을 탐지한다 - 무엇을 하고 싶은 건가?

XPath 표현식
//TryStatement/Block[1][count(*) = 0]
예제
public class Foo {
 public void bar() {
  try {
  } catch (Exception e) {
    e.printStackTrace();
  }
 }
}

빈 최종문 (EmptyFinallyBlock)

http://pmd.sourceforge.net/rules/basic.html#EmptyFinallyBlock

도입
PMD 0.4

이 규칙은 비어있는 최종문(finally)을 탐지한다 - 이 구문은 지워도 된다.

XPath 표현식
//FinallyStatement[count(Block/BlockStatement) = 0]
예제
public class Foo {
 public void bar() {
  try {
    int x=2;
   } finally {
    // empty!
   }
 }
}

빈 선택문 (EmptySwitchStatements)

http://pmd.sourceforge.net/rules/basic.html#EmptySwitchStatements

도입
PMD 1.0

이 규칙은 비어있는 선택문(switch)을 탐지한다.

XPath 표현식
//SwitchStatement[count(*) = 1]
예제
public class Foo {
 public void bar() {
  int x = 2;
  switch (x) {
   // once there was code here
   // but it's been commented out or something
  }
 }
}

뒤섞인 증가문 (JumbledIncrementer)

http://pmd.sourceforge.net/rules/basic.html#JumbledIncrementer

도입
PMD 1.0

이 규칙은 뒤섞인 증가문을 탐지한다. 이런 코드는 대부분 실수로 작성되며, 의도된 경우라도 혼란을 가져온다.

XPath 표현식
//ForStatement
 [
  ForUpdate/StatementExpressionList/StatementExpression/PostfixExpression/PrimaryExpression/PrimaryPrefix/Name/@Image
  =
  ancestor::ForStatement/ForInit//VariableDeclaratorId/@Image
 ]
예제
public class JumbledIncrementerRule1 {
  public void foo() {
   for (int i = 0; i < 10; i++) {
    for (int k = 0; k < 20; i++) {
     System.out.println("Hello");
    }
   }
  }
 }

For문을 While문으로 바꾸기 (ForLoopShouldBeWhileLoop)

http://pmd.sourceforge.net/rules/basic.html#ForLoopShouldBeWhileLoop

도입
PMD 1.02

For문 일부는 whlie문으로 바꿀 수 있다. 이게 더 간결하다.

XPath 표현식
//ForStatement
 [count(*) > 1]
 [not(ForInit)]
 [not(ForUpdate)]
 [not(Type and Expression and Statement)]
예제
public class Foo {
 void bar() {
  for (;true;) true; // No Init or Update part, may as well be: while (true)
 }
}

불필요한 임시 변환 (UnnecessaryConversionTemporary)

도입
PMD 1.02

이 규칙은 불필요한 기본형(primitive)의 문자열(String) 변환을 탐지한다.

이 규칙은 다음 자바 클래스에 정의되어 있다: net.sourceforge.pmd.rules.UnnecessaryConversionTemporary

예제
public String convert(int x) {
  // this wastes an object
  String foo = new Integer(x).toString();
  // this is better
  return Integer.toString(x);
}

Equals와 HashCode 재정의 (OverrideBothEqualsAndHashcode)

http://pmd.sourceforge.net/rules/basic.html#OverrideBothEqualsAndHashcode

도입
PMD 0.4

이 규칙은 두 메서드(public boolean Object.equals(Object other), public int Object.hashCode())를 모두 재정의하거나 아니면 둘 다 재정의하지 않았는지를 탐지한다. 만일 상위클래스로부터 hashCode() 메서드를 상속받았다 하더라도 명시적으로 하위클래스 자체의 hashCode() 메서드를 구현할 것을 권장한다.

이 규칙은 다음 자바 클래스에 정의되어 있다: net.sourceforge.pmd.rules.OverrideBothEqualsAndHashcode

예제
// this is bad
public class Bar {
  public boolean equals(Object o) {
      // do some comparison
  }
}

// and so is this
public class Baz {
  public int hashCode() {
      // return some hash value
  }
}

// this is OK
public class Foo {
  public boolean equals(Object other) {
      // do some comparison
  }
  public int hashCode() {
      // return some hash value
  }
}

이중 검사 잠금 (DoubleCheckedLocking)

http://pmd.sourceforge.net/rules/basic.html#DoubleCheckedLocking

도입
PMD 1.04

자바에서 이중 검사 잠금 패턴에 의해 객체가 부분적으로 생성되는 경우가 있습니다. 일부 JRE는 그 참조(reference)가 의도한 것과는 달리, 객체를 생성하기 이 전에 baz 변수에 참조를 할당하도록 최적화합니다. 자세한 것은 다음 문서를 보십시오: http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html

이중 검사 잠금 문서나 IBM developerWorks 기사를 참고하시기 바랍니다.

이 규칙은 다음 자바 클래스에 정의되어 있다: net.sourceforge.pmd.rules.DoubleCheckedLocking

예제
public class Foo {
  Object baz;
  Object bar() {
    if(baz == null) { //baz may be non-null yet not fully created
      synchronized(this){
        if(baz == null){
          baz = new Object();
        }
      }
    }
    return baz;
  }
}

Finally 블럭에서 결과 반환 (ReturnFromFinallyBlock)

http://pmd.sourceforge.net/rules/basic.html#ReturnFromFinallyBlock

도입
PMD 1.05

Finally 블럭에서 결과 반환은 피하십시오 - 이럴 경우 던져진 예외가 버려지게 됩니다.

XPath 표현식
//FinallyStatement//ReturnStatement
예제
public class Bar {
 public String foo() {
  try {
   throw new Exception( "My Exception" );
  } catch (Exception e) {
   throw e;
  } finally {
   return "A. O. K."; // Very bad.
  }
 }
}

빈 동기화 블럭 (EmptySynchronizedBlock)

http://pmd.sourceforge.net/rules/basic.html#EmptySynchronizedBlock

도입
PMD 1.3

빈 동기화 블럭 피하십시오 - 이건 쓸모가 없습니다.

XPath 표현식
//SynchronizedStatement/Block[1][count(*) = 0]
예제
public class Foo {
 public void bar() {
  synchronized (this) {
   // empty!
  }
 }
}

불필요한 반환 (UnnecessaryReturn)

도입
PMD 1.3

불필요한 반환문을 피하십시오.

이 규칙은 다음 자바 클래스에 정의되어 있다: net.sourceforge.pmd.rules.basic.UnnecessaryReturn

예제
public class Foo {
 public void bar() {
  int x = 42;
  return;
 }
}

빈 정적 초기화 블럭 (EmptyStaticInitializer)

http://pmd.sourceforge.net/rules/basic.html#EmptyStaticInitializer

도입
PMD 1.5

An empty static initializer was found.

빈 정적 초기화 블럭을 찾습니다.

XPath 표현식
//Initializer[@Static='true']/Block[count(*)=0]
예제
public class Foo {
 static {
  // empty
 }
 }

조건없는 If 구문 (UnconditionalIfStatement)

http://pmd.sourceforge.net/rules/basic.html#UnconditionalIfStatement

도입
PMD 1.5

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

항상 참이거나 거짓인 "if" 구문을 쓰지 마십시오.

XPath 표현식
//IfStatement/Expression
 [count(PrimaryExpression)=1]
 /PrimaryExpression/PrimaryPrefix/Literal/BooleanLiteral
예제
public class Foo {
 public void close() {
  if (true) {
       // ...
   }
 }
}

반복문 밖의 빈 구문 (EmptyStatementNotInLoop)

http://pmd.sourceforge.net/rules/basic.html#EmptyStatementNotInLoop

도입
PMD 1.5

for 반복문이나 while 반복문의 유일한 본문으로 사용되지 않은 (세미콜론 그 자체로도 알려진) 빈 구문은 아마도 버그일 것입니다. 혹은 삭제해야만 하는 연속된 세미콜론 쌍일 수도 있습니다.

XPath 표현식
//EmptyStatement
 [not(
       ../../../ForStatement
       or ../../../WhileStatement
       or ../../../BlockStatement/ClassOrInterfaceDeclaration
       or ../../../../../../ForStatement/Statement[1]
        /Block[1]/BlockStatement[1]/Statement/EmptyStatement
       or ../../../../../../WhileStatement/Statement[1]
        /Block[1]/BlockStatement[1]/Statement/EmptyStatement)
 ]
예제
public class MyClass {
   public void doit() {
      // this is probably not what you meant to do
      ;
      // the extra semicolon here this is not necessary
      System.out.println("look at the extra semicolon");;
   }
}

논리값 객체 생성 (BooleanInstantiation)

http://pmd.sourceforge.net/rules/basic.html#BooleanInstantiation

도입
PMD 1.2

논리값(Boolean) 객체의 생성을 피하십시오; 대신 Boolean.TRUE, Boolean.FALSE를 사용하거나 Boolean.valueOf() 메서드를 사용하십시오.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.basic.BooleanInstantiation

예제
public class Foo {
 Boolean bar = new Boolean("true"); // just do a Boolean bar = Boolean.TRUE;
 Boolean buz = Boolean.valueOf(false); // just do a Boolean buz = Boolean.FALSE;
}

불필요한 Final 수정자 (UnnecessaryFinalModifier)

http://pmd.sourceforge.net/rules/basic.html#UnnecessaryFinalModifier

도입
PMD 3.0

클래스가 final 수정자를 가지면 모든 메서드는 자동으로 final이 됩니다.

XPath 표현식
//ClassOrInterfaceDeclaration[@Final='true' and @Interface='false']
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/MethodDeclaration[@Final='true']
예제
public final class Foo {
    // This final modifier is not necessary, since the class is final
    // and thus, all methods are final
    private final void foo() {
    }
}

합칠 수 있는 If 문 (CollapsibleIfStatements)

http://pmd.sourceforge.net/rules/basic.html#CollapsibleIfStatements

도입
PMD 1.02

때론 두 if문은 각 조건을 논리적 최소 평가(short-circuit evaluation)로 나눔으로써 합칠 수 있습니다.

XPath 표현식
//IfStatement[@Else='false']/Statement
 /IfStatement[@Else='false']
 |
//IfStatement[@Else='false']/Statement
 /Block[count(BlockStatement)=1]/BlockStatement
  /Statement/IfStatement[@Else='false']
예제
public class Foo {
 void bar() {
  if (x) {
   if (y) {
    // do stuff
   }
  }
 }
}

쓸모없는 메서드 재정의 (UselessOverridingMethod)

http://pmd.sourceforge.net/rules/basic.html#UselessOverridingMethod

도입
PMD 3.3

재정의한 메서드가 단지 부모클래스의 동일한 메서드를 호출할 뿐입니다.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.UselessOverridingMethod

예제
public void foo(String bar) {
    super.foo(bar);      //Why bother overriding?
}
예제
public String foo() {
    return super.foo();  //Why bother overriding?
}
예제
@Id
public Long getId() {
    return super.getId();  //OK if 'ignoreAnnotations' is false, which is the default behavior
}


속성
이름 기본값 설명
ignoreAnnotations false 애노테이션을 무시한다.

ToArray에서 클래스 변환 예외 (ClassCastExceptionWithToArray)

http://pmd.sourceforge.net/rules/basic.html#ClassCastExceptionWithToArray

도입
PMD 3.4

컬렉션(Collection)에서 특정 클래스의 배열을 뽑아내기 위해선, toArray() 메서드에 원하는 클래스의 배열을 매개 변수에 전달해야 한다. 그렇지 않으면 ClassCaseException이 발생한다.

XPath 표현식
//CastExpression[Type/ReferenceType/ClassOrInterfaceType[@Image !=
"Object"]]//PrimaryExpression
[
 PrimaryPrefix/Name[ends-with(@Image, '.toArray')]
 and
 PrimarySuffix/Arguments[count(*) = 0]
and
count(PrimarySuffix) = 1
]
예제
import java.util.ArrayList;
import java.util.Collection;

public class Test {

    public static void main(String[] args) {
        Collection c=new ArrayList();
        Integer obj=new Integer(1);
        c.add(obj);

        // this would trigger the rule (and throw a ClassCastException if executed)
        Integer[] a=(Integer [])c.toArray();

        // this wouldn't trigger the rule
        Integer[] b=(Integer [])c.toArray(new Integer[c.size()]);
    }
}

AvoidDecimalLiteralsInBigDecimalConstructor

http://pmd.sourceforge.net/rules/basic.html#AvoidDecimalLiteralsInBigDecimalConstructor

도입
PMD 3.4

누군가 "new BigDecimal(.1)"이 .1과 정확히 같을 거라고 예상할 지도 모르겠지만, 사실 이 값은 .1000000000000000055511151231257827021181583404541015625과 같습니다. 왜냐하면 .1은 double형은 (혹은 크기가 제한된 그 어떤 이진 분수라면 그 어떤 것도) .1을 정확히 표현할 수 없기 때문입니다. 따라서 생성자에 전달된 긴 값은 그 형태가 보여주는 것과는 달리 정확히 .1이 아닙니다. 반면에 (String) 생성자는 정확하게 예측할 수 있습니다. 'new BigDecimal(".1")'는 여러분이 예측하는 것처럼 정확히 .1과 같습니다. 그러므로 이런 경우에 (String) 생성자를 사용하는 것을 권장합니다.

XPath 표현식
//AllocationExpression[ClassOrInterfaceType[@Image="BigDecimal"]
and
./Arguments/ArgumentList
/Expression/PrimaryExpression/PrimaryPrefix/Literal[(not
(ends-with
(@Image,'"'))) and contains(@Image,".")]]
예제
import java.math.BigDecimal;
public class Test {

    public static void main(String[] args) {
      // this would trigger the rule
     BigDecimal bd=new BigDecimal(1.123);
      // this wouldn't trigger the rule
     BigDecimal bd=new BigDecimal("1.123");
      // this wouldn't trigger the rule
     BigDecimal bd=new BigDecimal(12);
    }
}

불변객체에 대한 불필요한 연산 (UselessOperationOnImmutable)

http://pmd.sourceforge.net/rules/basic.html#UselessOperationOnImmutable

도입
PMD 3.5

불변객체(String, BigDecimal or BigInteger)에 대한 연산은 그 객체 자체를 변경시키지 않습니다. 그 연산 결과는 새 객체이며, 따라서 그 값을 버리는 것은 오류입니다.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.UselessOperationOnImmutable

예제
import java.math.*;
class Test {
 void method1() {
  BigDecimal bd=new BigDecimal(10);
  bd.add(new BigDecimal(5)); // this will trigger the rule
 }
 void method2() {
  BigDecimal bd=new BigDecimal(10);
  bd = bd.add(new BigDecimal(5)); // this won't trigger the rule
 }
}

잘못 위치한 널 검사 (MisplacedNullCheck)

http://pmd.sourceforge.net/rules/basic.html#MisplacedNullCheck

도입
PMD 3.5

여기서는 잘못 위치한 널 검사를 찾습니다. 어떤 값이 널이라면, 여러분은 NullPointerException를 만날 것입니다. 그 검사는 무용지물이거나 (그 값은 절대 "널"이 될 수 없는 경우), 아니면 잘못된 것입니다.

XPath 표현식
//Expression
    /*[self::ConditionalOrExpression or self::ConditionalAndExpression]
     /descendant::PrimaryExpression/PrimaryPrefix
      /Name[starts-with(@Image,
      concat(ancestor::PrimaryExpression/following-sibling::EqualityExpression
       [./PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
     /PrimaryExpression/PrimaryPrefix
      /Name[count(../../PrimarySuffix)=0]/@Image,"."))
    ]
예제
public class Foo {
 void bar() {
  if (a.equals(baz) && a != null) {}
 }
}
예제
public class Foo {
 void bar() {
  if (a.equals(baz) || a == null) {}
 }
}

Equals 내에서 사용되지 않는 널 검사 (UnusedNullCheckInEquals)

http://pmd.sourceforge.net/rules/basic.html#UnusedNullCheckInEquals

도입
PMD 3.5

객체 참조자의 널 여부를 검사한 다음에는 다른 객체의 equals()의 인자로 넘기기보단 널 여부를 검사한 객체의 equals() 메서드를 호출하는 게 낫습니다.

XPath 표현식
//PrimarySuffix[@Image='equals' and not(../PrimaryPrefix/Literal)]
 /following-sibling::PrimarySuffix/Arguments/ArgumentList/Expression
 /PrimaryExpression[count(PrimarySuffix)=0]/PrimaryPrefix
 /Name[@Image = ./../../../../../../../../../../Expression/ConditionalAndExpression
 /EqualityExpression[@Image="!=" and count(./preceding-sibling::*)=0 and
 ./PrimaryExpression/PrimaryPrefix/Literal/NullLiteral]
  /PrimaryExpression/PrimaryPrefix/Name/@Image]
예제
public class Test {

public String method1() { return "ok";}
public String method2() { return null;}

public void method(String a) {
String b;
/*
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 rule
a=method2();
if (method1().equals(a)) {
//whatever
}
}
}
}

ThreadGroup 지양 (AvoidThreadGroup)

http://pmd.sourceforge.net/rules/basic.html#AvoidThreadGroup

도입
PMD 3.6

java.lang.ThreadGroup을 피하십시오. 이 클래스는 쓰레드 환경에서 사용하도록 의도되었음에도 불구하고 쓰레드에 안전하지 않은 메서드를 포함하고 있습니다.

XPath 표현식
//AllocationExpression/ClassOrInterfaceType[typeof(@Image, 'java.lang.ThreadGroup')]|
//PrimarySuffix[contains(@Image, 'getThreadGroup')]
예제
    public class Bar {
     void buz() {
      ThreadGroup tg = new ThreadGroup("My threadgroup") ;
      tg = new ThreadGroup(tg, "my thread group");
      tg = Thread.currentThread().getThreadGroup();
      tg = System.getSecurityManager().getThreadGroup();
     }
    }

깨진 널 검사 (BrokenNullCheck)

http://pmd.sourceforge.net/rules/basic.html#BrokenNullCheck

도입
PMD 3.8

NullPointerException을 던지수 도 있는 널 검사는 잘못된 경우입니다. 이는 ||&& 대신에 잘못 쓰이거나, 그 반대의 경우에 일어납니다.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.BrokenNullCheck

예제
class Foo {
 String bar(String string) {
  // should be &&
  if (string!=null || !string.equals(""))
    return string;
  // should be ||
  if (string==null && string.equals(""))
    return string;
 }
}

BigInteger의 인스턴스 생성 (BigIntegerInstantiation)

http://pmd.sourceforge.net/rules/basic.html#BigIntegerInstantiation

도입
PMD 3.9

이미 존재하는 BigInteger의 인스턴스(BigInteger.ZERO, BigInteger.ONE), Java 1.5 이상에서는 BigInteger.TENBigDecimal의 인스턴스(BigDecimal.ZERO, BigDecimal.ONE, BigDecimal.TEN)를 새로 만들지 마십시오.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.BigIntegerInstantiation

예제
public class Test {

 public static void main(String[] args) {
   BigInteger bi=new BigInteger(1);
   BigInteger bi2=new BigInteger("0");
   BigInteger bi3=new BigInteger(0.0);
   BigInteger bi4;
   bi4=new BigInteger(0);
 }
}

8진수 사용 지양 (AvoidUsingOctalValues)

http://pmd.sourceforge.net/rules/basic.html#AvoidUsingOctalValues

도입
PMD 3.9

정수 리터럴은 0으로 시작하면 안 됩니다. 0은 리터럴의 나머지 부분이 8진수로 해석될 것임을 의미합니다.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.AvoidUsingOctalValues

예제
		public class Foo {
		  int i = 012; // set i with 10 not 12
		  int j = 010; // set j with 8 not 10
		  k = i * j; // set k with 80 not 120
		}

AvoidUsingHardCodedIP

http://pmd.sourceforge.net/rules/basic.html#AvoidUsingHardCodedIP

도입
PMD 4.1

하드 코딩된 IP를 포함한 애플리케이션은 때때로 배포가 불가능할 수 있습니다. IP 주소를 외부로 빼내는 것은 아무런 문제가 없습니다.

이 규칙은 다음 자바 클래스에 정의되어 있습니다: net.sourceforge.pmd.rules.AvoidUsingHardCodedIP

예제
	public class Foo {
	  String ip = "127.0.0.1"; // This is a really bad idea !
	}
속성
이름 기본값 설명
pattern ^"[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"$ 정규표현식

ResultSet 검사 (CheckResultSet)

http://pmd.sourceforge.net/rules/basic.html#CheckResultSet

도입
PMD 4.1

ResultSet의 위치 이동 메서드(next, previous, first, last)의 반환 값을 항상 검사하십시오. 개발자는 반환값을 확실히 검사해야만 합니다!

XPath 표현식
//Type/ReferenceType/ClassOrInterfaceType[
        (@Image = 'ResultSet')
        and
        (../../../descendant::Name[ends-with(@Image,'executeQuery')])
        and
        (
	(not (contains(
                        (./ancestor::Block/descendant::WhileStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.next')
		)  ) )
	and ( not ( contains(
                        (./ancestor::Block/descendant::IfStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.next')
		) ) )
	and (not (contains(
                        (./ancestor::Block/descendant::WhileStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.previous')
		)  ) )
	and ( not ( contains(
                        (./ancestor::Block/descendant::IfStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.previous')
		) ) )
	and ( not ( contains(
                        (./ancestor::Block/descendant::IfStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.last')
		) ) )
	and ( not ( contains(
                        (./ancestor::Block/descendant::IfStatement/descendant::Name/attribute::Image),
                        concat(../../../VariableDeclarator/VariableDeclaratorId/attribute::Image,'.first')
		) ) )

         )
]
예제
            // This is NOT appropriate !
            Statement stat = conn.createStatement();
            ResultSet rst = stat.executeQuery("SELECT name FROM person");
            rst.next(); // what if it returns a 'false' ?
            String firstName = rst.getString(1);

            // This is appropriate...
            Statement stat = conn.createStatement();
            ResultSet rst = stat.executeQuery("SELECT name FROM person");
            if (rst.next())
            {
                String firstName = rst.getString(1);
            }
            else
            {
                // here you deal with the error ( at least log it)
            }

여러 단항연산자 지양 (AvoidMultipleUnaryOperators)

http://pmd.sourceforge.net/rules/basic.html#AvoidMultipleUnaryOperators

도입
PMD 4.2

여러 단항연산자를 사용하면 버그를 만들기 쉽고 헷갈립니다. 이런 사용법이 버그가 아닌지 확인하고 표현식을 단순화할 것을 고려해 보십시오.

XPath 표현식
//UnaryExpression[
		./UnaryExpression
		or ./UnaryExpressionNotPlusMinus
		or ./PrimaryExpression/PrimaryPrefix/Expression/UnaryExpression
		or ./PrimaryExpression/PrimaryPrefix/Expression/UnaryExpressionNotPlusMinus
	]
|
//UnaryExpressionNotPlusMinus[
		./UnaryExpression
		or ./UnaryExpressionNotPlusMinus
		or ./PrimaryExpression/PrimaryPrefix/Expression/UnaryExpression
		or ./PrimaryExpression/PrimaryPrefix/Expression/UnaryExpressionNotPlusMinus
	]
예제
            // These are typo bugs, or at best needlessly complex and confusing:
            int i = - -1;
            int j = + - +1;
            int z = ~~2;
            boolean b = !!true;
            boolean c = !!!true;

            // These are better:
            int i = 1;
            int j = -1;
            int z = 2;
            boolean b = true;
            boolean c = false;

            // And these just make your brain hurt:
            int i = ~-2;
            int j = -~7;

빈 초기화 (EmptyInitializer)

http://pmd.sourceforge.net/rules/basic.html#EmptyInitializer

도입
PMD 5.0

빈 초기화가 발견된 경우입니다.

XPath 표현식
//Initializer/Block[count(*)=0]
예제
public class Foo {

   static {} // Why ?

   {} // Again, why ?

}

Thread.run()의 호출금지 (DontCallThreadRun)

http://pmd.sourceforge.net/rules/basic.html#DontCallThreadRun

도입
PMD 4.3

Thread.run() 메서드의 직접 실행은 호출한 컨트롤이 있는 쓰레드에서 이뤄집니다. 이보다는 의도한 동작을 위해서 Thread.start()를 호출하십시오.

XPath 표현식
//StatementExpression/PrimaryExpression
[
    PrimaryPrefix
    [
        ./Name[ends-with(@Image, '.run') or @Image = 'run']
        and substring-before(Name/@Image, '.') =//VariableDeclarator/VariableDeclaratorId/@Image
        [../../../Type/ReferenceType[ClassOrInterfaceType/@Image = 'Thread']]
        or (
        ./AllocationExpression/ClassOrInterfaceType[@Image = 'Thread']
        and ../PrimarySuffix[@Image = 'run'])
    ]
]
예제
Thread t = new Thread();
t.run();            // use t.start() instead
new Thread().run(); // same violation