| name | java-coding-style |
| description | Layer 2 (Coding style) for Java. Daily decisions without opening SKILL.md:
- 4 spaces (never tabs); K&R braces; always braces for if/for/while (no single-line).
- NO wildcard imports (`import x.*;`). NO `// comment` for structural blocks — use `/** */`.
- Every public class/method has Javadoc with @author/@date/@param/@return.
- Custom utility class: `public final class` + `private` ctor + all methods `static`. NO business imports.
- Discovery-first: prefer cn.hutool / commons / existing *Util before writing a new helper.
Open SKILL.md when deciding: In-Memory JOIN generic helper signature, Cursor Batching skeleton for large datasets, Javadoc template details.
|
Java Coding Style & Utility Standards
Trigger: You MUST read and follow this guide when writing, formatting, or reviewing ANY Java code to ensure structural and stylistic consistency.
💅 1. Formatting & Naming Conventions
BASE RULE: This project strictly enforces a combination of Google Java Style and Sun Code Conventions. When in doubt about formatting, default to Google Java Style.
- Indentation: ALWAYS use 4 spaces. NEVER use tabs.
- Line Wrapping: Wrap before the
. operator for chained methods (e.g., Stream API, MyBatis wrappers).
- Braces (K&R Style):
- Opening brace
{ on the same line.
- Closing brace
} on a new line.
- ALWAYS use braces for
if, else, for, while (no single-line omissions).
- Imports: NO wildcard imports (
import java.util.*; is strictly forbidden).
- Naming:
- Classes/Interfaces:
UpperCamelCase. Implementations MUST use the Impl suffix.
- Methods/Variables:
lowerCamelCase.
- Constants:
UPPER_SNAKE_CASE.
📝 2. Javadoc & Comments Standard
EVERY public element MUST have Javadoc. Do not use single-line // for structural comments.
Class-Level Javadoc (Required for all Controllers, Services, Entities):
Method-Level Javadoc (Required for all public methods):
Field-Level Javadoc (Required for ALL Entity/DTO/VO fields):
private Integer accountStatus;
Inline Comments: Use // 1. Step description to divide complex logic blocks inside methods.
🛠️ 3. Utility Classes & Anti-Reinvention
- Discovery First: NEVER reinvent the wheel. Always prefer established libraries (
cn.hutool.*, org.apache.commons.*) or existing project utilities (*Util, *Helper).
- Strict Boundaries: Custom utility classes MUST be stateless:
public final class with a private default constructor. All methods MUST be static.
- Acyclic Dependencies: Utility classes MUST NOT import business-level components (e.g.,
UserService or Entities).
🚀 4. Functional Programming & High-Performance Patterns
When writing complex data processing logic, you MUST use functional programming paradigms (Function, Consumer, BiConsumer) to abstract control flows.
Pattern A: In-Memory Data Assembly (Anti-JOIN)
Avoid nested for-loops when assembling cross-domain data. Parameterize the behavior:
public static <T, K, V> void assembleData(
List<T> source,
Function<T, K> keyExtractor,
Function<List<K>, Map<K, V>> valueLoader,
BiConsumer<T, V> resultSetter) {
}
Pattern B: High-Volume Cursor Batching (Anti-LIMIT/OFFSET)
STRICTLY PROHIBITED to load massive datasets into memory at once or use deep pagination (LIMIT offset, size). MUST use Cursor/IDX-based batch processing:
public static <T, C extends Comparable<C>> void processInBatches(
C initialCursor,
int batchSize,
BiFunction<C, Integer, List<T>> fetcher, // Query: WHERE id > cursor ORDER BY id ASC LIMIT batchSize
Function<T, C> cursorExtractor, // Extract cursor from the last element
Consumer<List<T>> batchConsumer // Consume the batch
) {
C currentCursor = initialCursor;
while (true) {
List<T> batch = fetcher.apply(currentCursor, batchSize);
if (batch == null || batch.isEmpty()) break;
batchConsumer.accept(batch);
currentCursor = cursorExtractor.apply(batch.get(batch.size() - 1));
}
}