Javaコードにおける一般的な悪習慣と改善策

Javaコードにおける一般的な悪習慣と改善策

Java開発でよく見られる「アンチパターン」をコードスキャンツール(https://github.com/pmd/pmd)から引用し、改善点を共有します。

1 - リソース管理

CloseResource: FileInputStreamなどのリソースは使用後に必ず閉じてください。

FileInputStreamやHttpClientのようなオブジェクトは使用後に適切にクローズする必要があります。

JDK 1.8以降では、try-with-resource構文を使用してリソースをクローズすることが推奨されます。なぜなら、複数のリソースや例外処理において、try-finally構文は最初の例外を失う可能性がありますが、try-with-resourceは最初の例外を保持し、後続の例外はSuppressed exceptionsとして扱われます。これらはgetSuppressed()メソッドで取得できます。

try-with-resourceの例:


try (FileReader fileReader = new FileReader(filePath);
    BufferedReader bufferedReader = new BufferedReader(fileReader)) {
    // 何らかの処理
}

2 - 疎結合

LooseCoupling: ArrayListのような実装型ではなく、インターフェースを使用してください。

具体的な実装型(ArrayListなど)の使用を避け、インターフェース(Listなど)を使用するべきです。


// 非推奨の方法:
public ArrayList<String> getDataList() {
    ArrayList<String> list = new ArrayList<String>();
    // 何らかの処理
    return list;
}

// 推奨される方法:
public List<String> getDataList() {
    List<String> list = new ArrayList<String>();
    // 何らかの処理
    return list;
}

2番目の方法の利点は、このメソッドの呼び出し元がメソッド内部でどのListの実装を使用しているかを気にする必要なく、メソッド内部の実装が変更されても呼び出し側のコードを変更する必要がないことです。

3 - NullPointerExceptionの回避

AvoidCatchingNPE - NullPointerExceptionをキャッチするのではなく、その原因を排除してください。

NullPointerExceptionをキャッチするのではなく、コード内でnull参照のチェックを行うべきです。

プログラムが実行時にNullPointerExceptionをスローするということは、null参照のデリファレンスが存在することを示しています。この種の問題はコード内で解決すべきです。

NullPointerExceptionを根本原因を処理せずにキャッチすることは適切ではありません:

  • 単純なnull参照チェックの代わりにNullPointerExceptionをキャッチするには、性能面でのコストがより高くなります。
  • tryブロック内の複数の式がNullPointerExceptionをスローする可能性がある場合、例外の発生位置を正確に判断できません。
  • プログラムがNullPointerExceptionをスローした後、正常な使用状態になることは稀です。

4 - String型の比較にはequals()メソッドを使用

UseEqualsToCompareStrings - '=='や'!='ではなくequals()を使用して文字列を比較してください。

String型を比較する際は、"=="や"!="ではなくequals()メソッドを使用してください。new String("")で構築されたオブジェクトを比較する場合、==はオブジェクトのアドレスを比較するため、この点に注意が必要です。

5 - null判定には"=="を使用

EqualsNull - nullとの比較にはequals()ではなく"=="を使用してください。

インスタンスがnullかどうか判定する際は、`str == null`のように"=="を使用し、`str.equals(null)`のようにしないでください。

6 - スタックトレースの直接出力を避ける

AvoidPrintStackTrace - printStackTrace()の使用を避け、ロガーを使用してください。

printStackTrace()メソッドで直接スタックトレースを出力するのではなく、ログフレームワークを使用してスタックトレース情報を出力してください。

7 - Integer型の初期化

IntegerInstantiation - new Integer()の使用を避け、Integer.valueOf()を使用してください。

new Integer(param)でIntegerオブジェクトを直接作成するのではなく、Integer.valueOf(param)を使用することを推奨します。

String型のパラメータの場合、Integer.parseInt()メソッドを使用して対応する数値型に解析する方が効率的です。

その他の型(Boolean、Long、Doubleなど)でも、Integerと同様の方法で解析してください。

8 - Boolean型の初期化

BooleanInstantiation - new Boolean()の使用を避け、Boolean.TRUE、Boolean.FALSE、またはBoolean.valueOf()を使用してください。

new Boolean(false)のようなBooleanオブジェクトの作成は避け、グローバルなBooleanインスタンスを使用してください。

Boolean型は1/0の2つの状態しかないため、Boolean.TRUEやBoolean.FALSE、またはBoolean.valueOf()を使用することを推奨します。

参考資料

https://github.com/pmd/pmd

タグ: Java コード品質 ベストプラクティス リファクタリング

6月9日 20:42 投稿