基本的なルールセットです。
空のcatchブロックを検出します。
try {
FileInputStream fis = new FileInputStream("/tmp/bugger");
} catch (IOException ioe) {
// 空のcatchブロック
}
コメントの付いた空ブロックを許可します。
try {
...
} catch (IOException ioe) {
// コメントの付いた空ブロックは許可する
} catch (SqlException e) {
}
// 二つ目の空ブロックはコメントが付いていないので検出される
空のifブロックを検出します。
if (x == 0) {
// 空のifブロック
}
空のwhileブロックを検出します。
while (a == b) {
// 空のwhileブロック
}
空のtryブロックを検出します。
try {
// 空のtryブロック
} catch (...) {
...
}
空のfinallyブロックを検出します。
try {
...
} finally {
// 空のfinallyブロック
}
空のswitchブロックを検出します。
switch (x) {
// 空のswitchブロック
}
間違ったインクリメント文を検出します。
for (int i = 0; i < 10; i++) {
for (int k = 0; k < 20; i++) { // k++の間違い
...
}
}
forループがありますが、while文に置き換えるべきです。
for (;true;) { // これは while (true) で置き換えるべき
...
}
不必要な文字列変換処理を検出します。
String waste = new Integer(x).toString(); // このnewは不必要 String better = Integer.toString(x); // こちらの方が良い
equals(Object other) と hashCode() の片方しか定義されていないクラスを検出します。
通常これらは両方定義しなければ正常に機能しません。
"double-checked locking" ロジックを検出します。
if(baz == null) {
synchronized(this){
if(baz == null){
baz = new Object();
}
}
}
finallyブロックからのreturn文を検出します。
try {
throw new Exception( "My Exception" );
} catch (Exception e) {
throw e;
} finally {
return "A. O. K.";
}
空のsynchronizedブロックを検出します。
synchronized (this) {
// 空のsynchronizedブロック
}
不必要なreturn文を検出します。
public void bar() {
int x = 42;
return;
}
空のクラス初期化ブロックを検出します。
static {
// 空のクラス初期化ブロック
}
条件が定数値のif文を検出します。
if (true) {
// 常にこのブロックは実行される。if文は必要無い
}
空文をチェックします。
; // これは空文 func();; // 2つ目のセミコロンは空文
new Boolean(...) を検出します。
r = new Boolean(false); // Boolean.FALSE とした方が良い
不必要なfinal記述子を検出します。
public final class Foo {
private final void foo() { // finalクラスのメソッドは暗黙的に全てfinalになる
}
}
短縮可能な複数if文を検出します。
if (x) {
if (y) {
// 上の2文は、if (x && y) に短縮できる
}
}
意味の無いオーバーライドメソッドを検出します。
public void foo(String bar) {
super.foo(bar);
}
// スーパークラスと全く同じ事をやっているだけ
ClassCastException が発生するような toArray メソッドを使っている箇所を検出します。
Collection c = new ArrayList(); (Integer[])c.toArray(); // toArray()はObject[]を返すので、Integer[]にキャスト不可能 (Integer[])c.toArray(new Integer[c.size()]); // これが正解
BigDecimal コンストラクタの引数に小数値を与えている箇所を検出します。
new BigDecimal(1.123); // 精度が失われる可能性がある
new BigDecimal("1.123"); // これはOK
BigDecimal および BigInteger はImmutable(不変)オブジェクトです。
これに対する無意味なロジックを検出します。
BigDecimal bd = new BigDecimal(10); System.out.println(bd); bd.add(new BigDecimal(5)); // bdの内容は変化しない。無意味なロジック System.out.println(bd); // 10 を出力 bd = bd.add(new BigDecimal(5)); // bdの内容が変化する System.out.println(bd); // 15 を出力
間違った箇所でのnullチェックを検出します。
if (a.equals("hi") && a != null) {
// 上のnullチェックは間違っている
}
if (a != null && a.equals("hi")) {
// これが正しい
}
nullチェックとequalsメソッド呼出の不適切な組み合わせを検出します。
if (a != null && method1().equals(a)) {
// a のnullチェックをしているので、a.equals() とするべき
// これだと、method1() がnullを返した場合に例外が発生してしまう
}
if (a != null && a.equals(method1())) {
// method1() がnullを返す場合でも、この記述法ならば例外は発生しない
}
ThreadGroup の使用を検出します。
このクラスはスレッドセーフではないメソッドを持っており、使用は推奨されません。
間違ったnullチェックを検出します。
if (string != null || !string.equals("")) {
// 上のは間違い。正しくは && を使う
}
if (string == null && string.equals("")) {
// 上のは間違い。正しくは || を使う
}
BigIntegerおよびBigDecimalには ZERO / ONE / TEN の定数が定義されています。
これらをインスタンス化する必要はありません。
new BigInteger(10); // これは BigInteger.TEN とする
Javaでは数値を表現するとき、先頭に0を記述すると8進数表記だと見なされます。
わかりにくいので避けたほうが良いでしょう。
int i = 012; // 12ではなく10 int j = 010; // 10ではなく8
|
|