minimize

Controversial

問題のありそうなロジックを検出するルールセットです。

UnnecessaryConstructor

不必要なコンストラクタ宣言を検出します。

public class Foo {
  public Foo() {}
}

NullAssignment

変数宣言文以外でのnull値の代入を検出します。

Object x = null; // これはOK
x = new Object();
x = null; // これはNG

一般的に、これは悪い形式のコーディングだとされています。
昔の記事にはよく、
「明示的にnullにしないとガーベッジコレクト(以下GC)されないのでnullを代入する事」
などという事が書いてありましたが、これは一般的には
ロジックそのものに何らかの間違いがある事を意味しています。

ただし、一部のソートロジックでは明示的なnull値の代入が
GCの効率を上げるために有用である事もあります。
その事に自信があるのなら、この警告を無視しても構わないでしょう。

OnlyOneReturn

メソッドの最後以外にreturn文があるロジックを検出します。
つまりこのルールは、メソッドの最後に唯一のreturn文がある事を期待します。

public void foo(int x) {
  if (x > 0) {
    return "hey";   // メソッドの途中にあるreturn文
  }
  return "hi";
}

UnusedModifier

不必要な識別子の記述を検出します。

public interface Foo {
  public abstract void bar(); // public abstract は必要無い
  public static final int X = 0; // public static final は必要無い
}

AssignmentInOperand

オペランド中の代入ロジックを検出します。

if ((x = getX()) == 10) { // 読みにくいので止めた方がいい
  ...
}

AtLeastOneConstructor

コンストラクタが一つも定義されていないクラスを検出します。
この場合、クラスには引数無のデフォルトコンストラクタが作成されますが
これに頼ったコーディングは、思わぬところで弊害を引き起こす可能性があります。

DontImportSun

sun. で始まるimport文を検出します。
これらは通常、明示的にソースに記述すべきではありません。

SuspiciousOctalEscape

疑わしい8進数表記を検出します。

s = "\123"; // これは "\123" と見なされる
s = "\128"; // これは "\12" + "8" と見なされる(8進数に8は使えない為)

CallSuperInConstructor

コンストラクタ内で super または this が呼び出されていないロジックを検出します。

public Foo() {
  this.cnt = 10; // これはNG
}

public Foo() {
  super(); // これはOK
}

public Foo() {
  this(10); // これもOK
}

UnnecessaryParentheses

不必要な括弧を検出します。

return (true); // この括弧は不必要

SingularField

1箇所からしか使用されていないフィールドを検出します。
通常、これはローカル変数化できます。

private int x; // このフィールドは1箇所からしか使われていない
public void foo(int y) {
   x = y + 5;
   return x;
}

DefaultPackage

アクセス識別子を指定していない箇所を検出します。
この場合、パッケージprivateとなります。これはあまり推奨されません。

public class Foo {
  int bar; // アクセス識別子が指定されていない
}

BooleanInversion

最適化されていないBoolean値の反転ロジックを検出します。

b = !b; // これは以下のようにする
b ^= true; // …いや、まぁ確かに。でも正直言ってわかりにくいと思いません?

DataflowAnomalyAnalysis

不自然なデータフローを検出します。

{
  int buz = 5; // この値はどこからも使われていない
  buz = 6;
  foo(buz);
  buz = 2; // buzへ代入しているが、以降どこからも参照されていない
}
maxviolations

一つのクラスで検出する最大警告数を制限します。
デフォルト値は100です。

maxpaths

一つのメソッドでチェックする最大パス数を制限します。
デフォルト値は1000です。
この値を小さくするとパフォーマンスは上がりますが、検出できる数も減ります。

AvoidFinalLocalVariable

final のローカル変数を検出します。

public void foo() {
    final String finalLocalVariable;
}

Javaの言語仕様上、無名クラスから参照可能にするために
ローカル変数を final にすることはよくありますが、これは良くないとされているようです。

AvoidUsingShortType

short 型の変数定義を検出します。
これもJavaの言語仕様に対してなかなか挑戦的なチェックです。

PMDのサイトによれば、short は int に比べてメモリ量の節約にはなるが
(int は4バイト、shortは2バイト)
shortを計算するときには一旦intに変換してまたshortに変換するという
ロジックが走り、結局intより多くのメモリ量を使うことになると主張しています。

確かに、メモリ節約という理由だけでshortを使うのはあまり良いことではないと僕も思います。

AvoidUsingVolatile

volatile キーワードの使用を検出します。
詳しい理由はわかりませんが、volatileキーワードの安易な使用は
控えるべきだという主張のようです。
JDK5以降は concurrent というマルチスレッドに対応するパッケージが用意されていますから
これを使った方がいいということなのでしょう。

AvoidUsingNativeCode

System.loadLibrary メソッドの使用を検出します。
これはネイティブ関数を使うためのものですが、
プラットフォーム非依存というJavaのメリットを消してしまいます。

AvoidAccessibilityAlteration

AccessibleObject.setAccessible などを
PrivilegedAction 外で呼び出している箇所を検出します。

DoNotCallGarbageCollectionExplicitly

System.gc(), Runtime.getRuntime().gc(), System.runFinalization() の
呼び出しを検出します。

[コメント(0)]