Everything-claude-code java-coding-standards
Spring Bootサービス向けのJavaコーディング標準:命名、不変性、Optional使用、ストリーム、例外、ジェネリクス、プロジェクトレイアウト。
install
source · Clone the upstream repo
git clone https://github.com/affaan-m/everything-claude-code
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/affaan-m/everything-claude-code "$T" && mkdir -p ~/.claude/skills && cp -r "$T/docs/ja-JP/skills/java-coding-standards" ~/.claude/skills/affaan-m-everything-claude-code-java-coding-standards && rm -rf "$T"
manifest:
docs/ja-JP/skills/java-coding-standards/SKILL.mdsource content
Javaコーディング標準
Spring Bootサービスにおける読みやすく保守可能なJava(17+)コードの標準。
核となる原則
- 巧妙さよりも明確さを優先
- デフォルトで不変; 共有可変状態を最小化
- 意味のある例外で早期失敗
- 一貫した命名とパッケージ構造
命名
// PASS: クラス/レコード: PascalCase public class MarketService {} public record Money(BigDecimal amount, Currency currency) {} // PASS: メソッド/フィールド: camelCase private final MarketRepository marketRepository; public Market findBySlug(String slug) {} // PASS: 定数: UPPER_SNAKE_CASE private static final int MAX_PAGE_SIZE = 100;
不変性
// PASS: recordとfinalフィールドを優先 public record MarketDto(Long id, String name, MarketStatus status) {} public class Market { private final Long id; private final String name; // getterのみ、setterなし }
Optionalの使用
// PASS: find*メソッドからOptionalを返す Optional<Market> market = marketRepository.findBySlug(slug); // PASS: get()の代わりにmap/flatMapを使用 return market .map(MarketResponse::from) .orElseThrow(() -> new EntityNotFoundException("Market not found"));
ストリームのベストプラクティス
// PASS: 変換にストリームを使用し、パイプラインを短く保つ List<String> names = markets.stream() .map(Market::name) .filter(Objects::nonNull) .toList(); // FAIL: 複雑なネストされたストリームを避ける; 明確性のためにループを優先
例外
- ドメインエラーには非チェック例外を使用; 技術的例外はコンテキストとともにラップ
- ドメイン固有の例外を作成(例:
)MarketNotFoundException - 広範な
を避ける(中央でリスロー/ログ記録する場合を除く)catch (Exception ex)
throw new MarketNotFoundException(slug);
ジェネリクスと型安全性
- 生の型を避ける; ジェネリックパラメータを宣言
- 再利用可能なユーティリティには境界付きジェネリクスを優先
public <T extends Identifiable> Map<Long, T> indexById(Collection<T> items) { ... }
プロジェクト構造(Maven/Gradle)
src/main/java/com/example/app/ config/ controller/ service/ repository/ domain/ dto/ util/ src/main/resources/ application.yml src/test/java/... (mainをミラー)
フォーマットとスタイル
- 一貫して2または4スペースを使用(プロジェクト標準)
- ファイルごとに1つのpublicトップレベル型
- メソッドを短く集中的に保つ; ヘルパーを抽出
- メンバーの順序: 定数、フィールド、コンストラクタ、publicメソッド、protected、private
避けるべきコードの臭い
- 長いパラメータリスト → DTO/ビルダーを使用
- 深いネスト → 早期リターン
- マジックナンバー → 名前付き定数
- 静的可変状態 → 依存性注入を優先
- サイレントなcatchブロック → ログを記録して行動、または再スロー
ログ記録
private static final Logger log = LoggerFactory.getLogger(MarketService.class); log.info("fetch_market slug={}", slug); log.error("failed_fetch_market slug={}", slug, ex);
Null処理
- やむを得ない場合のみ
を受け入れる; それ以外は@Nullable
を使用@NonNull - 入力にBean Validation(
、@NotNull
)を使用@NotBlank
テストの期待
- JUnit 5 + AssertJで流暢なアサーション
- モック用のMockito; 可能な限り部分モックを避ける
- 決定論的テストを優先; 隠れたsleepなし
覚えておく: コードを意図的、型付き、観察可能に保つ。必要性が証明されない限り、マイクロ最適化よりも保守性を最適化します。