Files
everything-claude-code/rules/java/coding-style.md
Chris Yau 9ceb699e9a feat(rules): add Java language rules (#645)
Adds Java language rules (coding-style, hooks, patterns, security, testing) following the established language rule conventions.
2026-03-19 20:49:21 -07:00

3.4 KiB

paths
paths
**/*.java

Java Coding Style

This file extends common/coding-style.md with Java-specific content.

Formatting

  • google-java-format or Checkstyle (Google or Sun style) for enforcement
  • One public top-level type per file
  • Consistent indent: 2 or 4 spaces (match project standard)
  • Member order: constants, fields, constructors, public methods, protected, private

Immutability

  • Prefer record for value types (Java 16+)
  • Mark fields final by default — use mutable state only when required
  • Return defensive copies from public APIs: List.copyOf(), Map.copyOf(), Set.copyOf()
  • Copy-on-write: return new instances rather than mutating existing ones
// GOOD — immutable value type
public record OrderSummary(Long id, String customerName, BigDecimal total) {}

// GOOD — final fields, no setters
public class Order {
    private final Long id;
    private final List<LineItem> items;

    public List<LineItem> getItems() {
        return List.copyOf(items);
    }
}

Naming

Follow standard Java conventions:

  • PascalCase for classes, interfaces, records, enums
  • camelCase for methods, fields, parameters, local variables
  • SCREAMING_SNAKE_CASE for static final constants
  • Packages: all lowercase, reverse domain (com.example.app.service)

Modern Java Features

Use modern language features where they improve clarity:

  • Records for DTOs and value types (Java 16+)
  • Sealed classes for closed type hierarchies (Java 17+)
  • Pattern matching with instanceof — no explicit cast (Java 16+)
  • Text blocks for multi-line strings — SQL, JSON templates (Java 15+)
  • Switch expressions with arrow syntax (Java 14+)
  • Pattern matching in switch — exhaustive sealed type handling (Java 21+)
// Pattern matching instanceof
if (shape instanceof Circle c) {
    return Math.PI * c.radius() * c.radius();
}

// Sealed type hierarchy
public sealed interface PaymentMethod permits CreditCard, BankTransfer, Wallet {}

// Switch expression
String label = switch (status) {
    case ACTIVE -> "Active";
    case SUSPENDED -> "Suspended";
    case CLOSED -> "Closed";
};

Optional Usage

  • Return Optional<T> from finder methods that may have no result
  • Use map(), flatMap(), orElseThrow() — never call get() without isPresent()
  • Never use Optional as a field type or method parameter
// GOOD
return repository.findById(id)
    .map(ResponseDto::from)
    .orElseThrow(() -> new OrderNotFoundException(id));

// BAD — Optional as parameter
public void process(Optional<String> name) {}

Error Handling

  • Prefer unchecked exceptions for domain errors
  • Create domain-specific exceptions extending RuntimeException
  • Avoid broad catch (Exception e) unless at top-level handlers
  • Include context in exception messages
public class OrderNotFoundException extends RuntimeException {
    public OrderNotFoundException(Long id) {
        super("Order not found: id=" + id);
    }
}

Streams

  • Use streams for transformations; keep pipelines short (3-4 operations max)
  • Prefer method references when readable: .map(Order::getTotal)
  • Avoid side effects in stream operations
  • For complex logic, prefer a loop over a convoluted stream pipeline

References

See skill: java-coding-standards for full coding standards with examples. See skill: jpa-patterns for JPA/Hibernate entity design patterns.