Java | 基礎文法:コーディング規約

Java Java
スポンサーリンク

コーディング規約の全体像

コーディング規約は「チーム全体でコードの見た目と書き方を揃えるための約束事」です。読みやすさ、保守性、バグ回避、ツール連携を高めます。Javaでは命名、インデント、改行、波括弧の位置、importの扱い、例外処理、コメント/JavaDocなどを統一するのが基本です。重要なのは「論理は自由、表現は統一」。規約を守るとレビュー効率と学習コストが大幅に下がります。


スタイルの基本(命名・インデント・括弧・改行)

命名規約(クラス・メソッド・変数・定数)

  • クラス名: UpperCamelCase(例:OrderService, UserRepository)
  • メソッド名/変数名: lowerCamelCase(例:calculateTotal, maxRetryCount)
  • 定数: 全大文字+アンダースコア(例:DEFAULT_TIMEOUT_MS, MAX_ITEMS)
  • 真偽値: 質問文の接頭辞(例:isActive, hasError, shouldRetry, canSubmit)
public final class OrderService {
    private static final int MAX_RETRY = 3;
    public boolean hasValidStatus(String status) { ... }
}
Java

インデントと行長

  • インデント幅: 4スペース(タブではなくスペース推奨)
  • 最大行長: 100〜120桁を目安に折り返し(長すぎる式は分解)
// 長い呼び出しは改行して揃える
var result = client
    .withTimeout(Duration.ofSeconds(2))
    .withRetry(MAX_RETRY)
    .execute(request);
Java

波括弧の位置と空白

  • 括弧スタイル: メソッド・クラスの開き括弧は改行して同列、制御構文は同行(K&R 系)
  • 空白: 演算子の前後、カンマ後に入れる
if (count > 0) {
    total += count;
} else {
    total += 1;
}
Java

空行で意味の塊を分ける

  • 意味のまとまり: フィールド宣言、コンストラクタ、公開メソッドの間に1行空けて区切る

import とパッケージ、可視性の指針(重要ポイントの深掘り)

import の扱い

  • 個別 import: ワイルドカード(*)は原則避ける(衝突を防ぐ)
  • 不要 import: IDEで削除、整形ツールで自動化
import java.util.List;      // 個別
// import java.util.*;      // 原則避ける
Java

パッケージ構成

  • 逆ドメイン+機能: com.example.app.user, com.example.app.order
  • 役割分離: model/service/controller/infra など層で分ける

アクセス修飾子の最小化

  • 最小公開: 必要最小限だけ public、内部は package-private を活用
  • 不変設計: 変更が外へ漏れない境界を保つ
class InternalHelper { /* 同パッケージ内のみ */ }
public class PublicApi { /* 公開 */ }
Java

例外処理とエラーハンドリング(重要ポイントの深掘り)

チェック例外と実行時例外の使い分け

  • チェック例外: 呼び出し側で回復可能な状況(IO, SQL)
  • 実行時例外: バグや契約違反(IllegalArgumentException, IllegalStateException)
public void load(Path p) throws IOException {
    try (var br = Files.newBufferedReader(p)) { ... }
}
Java

メッセージと原因例外の連鎖

  • 原因の保持: new XxxException(“説明”, cause) でラップ
  • メッセージの具体化: 入力値・状態・期待値を含める
try {
    service.process(req);
} catch (SQLException e) {
    throw new IllegalStateException("DB処理失敗: reqId=" + req.id(), e);
}
Java

早期 return とガード節

  • 前提違反は早期に弾く: requireNonNull、範囲チェックで分岐を浅く
Objects.requireNonNull(name, "name must not be null");
if (name.isBlank()) return;
Java

コメントと JavaDoc、テスト可能性のための設計

コメント/JavaDocの方針

  • 「なぜ」を書く: コードが語る「何」を繰り返さない
  • JavaDoc: 公開メソッドは契約(前提・戻り値・例外)を明記
/**
 * 税込金額を計算する。
 * @param subtotal 税抜金額(0以上)
 * @param taxRate 税率(0〜1)
 * @return 税込金額
 */
public int taxed(int subtotal, double taxRate) { ... }
Java

テストしやすさを規約で担保

  • 副作用の分離: 計算ロジックとI/Oを分ける
  • 小さなメソッド: 1つの責務、短い引数リスト
int calcTaxed(int price, double rate) { ... } // 純粋関数に近くする
Java

クラス設計と不変性、equals/hashCode/toString

不変オブジェクトの推奨

  • final フィールド: コンストラクタで初期化、セッター不要
  • レコード活用: Java 16+ の record で不変値オブジェクトを簡潔に
public record User(String id, String name) { }
Java

equals/hashCode の一貫性

  • 契約に基づき実装: 同値なら同じ hashCode
  • **IDE生成/Objects.equals/Objects.hash を使用
@Override public boolean equals(Object o) { ... }
@Override public int hashCode() { return Objects.hash(id, name); }
Java

toString はデバッグに有用

  • 短く要点: 主要フィールドのみ、機密情報は含めない
@Override public String toString() { return "User{id=" + id + ", name=" + name + "}"; }
Java

ログ、フォーマット、定数・列挙の扱い(重要ポイントの深掘り)

ログの書き方

  • レベル選択: info=業務進捗、warn=要注意、error=失敗、debug=詳細
  • 構造化: キー=値で出力、後で検索しやすく
logger.info("order_created id={} user={}", orderId, userId);
Java

フォーマットと国際化

  • 書式化: String.format / printf を使用、小数/桁区切りは Locale 指定
  • 日時: DateTimeFormatter(ISO かロケール適合)
var s = String.format(Locale.JAPAN, "%,d円", 1234567);
Java

定数と enum

  • 魔法の数値を排除: static final へ
  • 区分値は enum: 安全な型で表現
public enum Status { NEW, PROCESSING, DONE }
Java

自動整形と静的解析、チーム運用

ツールを前提にした規約

  • フォーマッタ: Spotless/Google Java Format/IDEのCode Styleで自動整形
  • Lint: Checkstyle, PMD, Error Prone で規約違反やバグの芽を検出

PR レビューの役割分担

  • 形式はツールに任せる: レビューは設計・命名・契約に集中
  • 規約の例外は明文化: 性能・互換性のために外れる場合はコメントで理由を残す

例題で身につける

例 1: 規約に沿ったメソッドの形

public final class PriceCalculator {
    private static final double TAX_RATE = 0.1;

    /**
     * 税込金額を返す。
     * @param subtotal 税抜金額(0以上)
     * @return 税込金額
     * @throws IllegalArgumentException 引数が負の場合
     */
    public static int calc(int subtotal) {
        if (subtotal < 0) throw new IllegalArgumentException("subtotal must be >= 0");
        return (int) Math.round(subtotal * (1 + TAX_RATE));
    }
}
Java

例 2: import と命名を整えたコレクション操作

import java.util.ArrayList;
import java.util.List;

public class Users {
    public static List<String> activeUserNames(List<String> userNames) {
        List<String> result = new ArrayList<>();
        for (String name : userNames) {
            if (name != null && !name.isBlank()) result.add(name.trim());
        }
        return result;
    }
}
Java

例 3: 例外連鎖とログの一貫性

public class Repository {
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Repository.class);

    public User find(String id) {
        try {
            // DBアクセス...
            return new User(id, "Sato");
        } catch (Exception e) {
            log.error("find_failed id={}", id, e);
            throw new IllegalStateException("find failed id=" + id, e);
        }
    }
}
Java

仕上げのアドバイス(重要部分のまとめ)

  • 命名は「意味・単位・状態」を含め、スタイルは camelCase/定数は大文字スネークに統一。
  • インデントは4スペース、行長は100〜120桁目安、括弧と空白は規約どおりに。
  • import は個別指定、可視性は最小限、例外は原因を連鎖させメッセージを具体化。
  • コメントは「なぜ」を、JavaDocは契約を。テストしやすい純粋なロジックに寄せる。
  • 不変設計、equals/hashCode/toStringの一貫性、enumと定数で魔法値を排除。
  • 形式はツールで自動化し、レビューは設計と意味へ集中する。

タイトルとURLをコピーしました