Sponsored link
PMD Basic ルール
基本的に、空の制御文やらに対して引っかかります。
あとはまっとうに書いていればまず引っかかることはないので
ぜひともチェックしたいルールです。ただ、tryとかifとか空にしたい所をどう美しく書くかは課題です。
ルールから抜くべきかどうか迷うところです。
EmptyCatchBlock(空のCatch文)
僕もerrでたらnullでいいだろうでよくやりますが引っかかります。
//よくない例
public void doSomething() {
try {
FileInputStream fis = new FileInputStream("/tmp/bugger");
} catch (IOException ioe) {
// not good
}
}
以後、明示的に、回避するにはどうしよう。
メモリ食うのもいやだし。わかりやすくしないといけないし
めっちゃ不細工やけど、どうでしょうか。
//改善例
public void doSomething() {
try {
FileInputStream fis = new FileInputStream("/tmp/bugger");
} catch (IOException ioe) {
"PMD".toString();
}
}
EmptyIfStmt(空のIf 制御文)
これもよくやるんですよね。特に、メンタル的に
if(!)つかうよりelse使いたいときに
//よくない例
if (absValue < 1) {
// not good
}else{
return 1;
}
//改善例
if (absValue < 1) {
"PMD".toString();
}else{
return 1;
}
EmptyWhileStmt(Whileの中が空)
時間潰すならThread.sleep()を呼んでくれ。
//よくない例
while (a == b) {
// not good
}
EmptyTryBlock(try内が空)
//よくない例
public void bar() {
try {
} catch (Exception e) {
e.printStackTrace();
}
}
EmptyFinallyBlock(finaly内が空)
//よくない例
public void bar() {
try {
int x=2;
} finally {
}
}
EmptySwitchStatements(switch制御文が空)
//よくない例
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(incrementが混ざってる?)
以下の例は、普通間違いです。これは結構見つけにくいバグです。
//よくない例
public class JumbledIncrementerRule1 {
public void foo() {
for (int i = 0; i < 10; i++) {
for (int k = 0; k < 20; i++) {
System.out.println("Hello");
}
}
}
}
ForLoopShouldBeWhileLoop(Whileの代わりにForを使う)
Whileを使うべき
//よくない例
public class Foo {
void bar() {
for (;true;) true; // No Init or Update part, may as well be: while (true)
}
}
UnnecessaryConversionTemporaryRule(不必要なテンポラリーオブジェクト生成する)
これは無駄なオブジェクトを作るなということ
//よくない例 String x=new Integer(v).toString(); こっちにしましょう。 //改善例 String x=Integer.toString(v);
OverrideBothEqualsAndHashcodeRule(equalとhashCodeは同時に実装すべき)
equals()メソッドを書き換えるときは、hashCode()も書き換えるべきだというルール
DoubleCheckedLockingRule(Singleton等でのdoublecheckは使用不可)
JavaWorld
にはstaticにしてクラスの初期化で作れとかいてるね。
DoubleCheck
回避策はなど3つ
一つは、singletonは非同期で初期化時に生成する。
二つめは、動作速度は無視してメソッドはsynchronizedする。
三つめは、動作時にはJVMを指定する。(JVM違えば動かないコード山ほどあるし)
ただこの場合万が一動かない場合DoubleCheckedという可能性があるということを忘れてはいけない。
//よくない例
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;
}
}
ReturnFromFinallyBlock(FinalyからReturn呼ぶ)
Exceptionが呼ばれないのでダメですとのこと
//よくない例
public class Bar {
public String bugga() {
try {
throw new Exception( "My Exception" );
} catch (Exception e) {
throw e;
} finally {
return "A. O. K."; // Very bad.
}
}
}
EmptySynchronizedBlock(synchronized内でなにもしない)
意味ありません。
//よくない例
// this is bad
public void bar() {
synchronized (this) {}
}
UnnecessaryReturn(必要がないリターン)
//よくない例
// this is bad
public void bar() {
int x = 42;
return;
}
EmptyStaticInitializer(static初期化なにもしない)
何も書かないのはよくないです。
//よくない例
public class Foo {
// why are there no statements in this static block?
static {}
}
UnconditionalIfStatement(Ifのなかに、trueやfalseの直接書くのはよくない
bollean等の変数名だとOK
//よくない例
public class Foo {
public void close() {
if (true) {
// ...
}
}
}
//改善例
public class Foo {
public void close() {
boolean bool=true;
if (bool) {
// ...
}
}
}
EmptyStatementNotInLoop(ループ内以外での意味のない;はダメ)
//よくない例
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");;
}
}
