Communitygithub.com

Java编码规范

适用于Spring Boot和Quarkus服务的Java编码规范,涵盖命名、不可变性、Optional使用、Stream、异常处理、泛型、CDI、响应式模式和项目结构。可自动应用框架特定的约定,在编写或审查Spring Boot或Quarkus服务中的Java代码时使用。

Java编码规范 是什么?

该技能为Spring Boot和Quarkus服务提供了一套全面的Java编码规范。其核心原则包括优先考虑清晰性而非技巧性、默认不可变性、快速失败并提供有意义的异常信息、以及一致的命名和包结构。技能会根据构建文件自动检测框架(Quarkus或Spring Boot),并应用框架特定的约定。例如,在Spring Boot中倾向于使用构造器注入而非字段注入,而在Quarkus中则允许包私有字段注入。此外,技能还涵盖了Optional的正确使用方法、Stream的最佳实践、响应式编程模式(针对Quarkus的Uni/Multi)、异常处理(包括集中式异常处理示例)、泛型和类型安全、项目结构布局、日志记录、Null处理以及配置管理。最后,技能还提供了针对不同框架的测试建议,包括JUnit 5、Mockito以及Spring Boot和Quarkus的特有测试注解。该技能适用于任何需要编写、审查或维护Java 17+代码的开发者,以确保代码的可读性和可维护性。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/java-coding-standards

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Java编码规范 是做什么的?

适用于Spring Boot和Quarkus服务的可读、可维护Java(17+)代码规范。

何时使用

  • 编写或审查Spring Boot或Quarkus项目中的Java代码
  • 强制执行命名、不可变性或异常处理约定
  • 使用records、sealed classes或pattern matching(Java 17+)
  • 审查Optional、Stream或泛型的使用
  • 组织包结构和项目布局
  • [QUARKUS]:处理CDI作用域、Panache实体或响应式管道

工作原理

框架检测

在应用规范前,通过构建文件确定框架:

  • 构建文件包含quarkus → 应用**[QUARKUS]**约定
  • 构建文件包含spring-boot → 应用**[SPRING]**约定
  • 二者均未检测到 → 仅应用共享约定

核心原则

  • 优先考虑清晰性而非技巧性
  • 默认不可变;最小化共享可变状态
  • 快速失败,提供有意义的异常信息
  • 一致的命名和包结构
  • [QUARKUS]:优先构建时处理而非运行时处理;尽可能避免运行时反射

示例

以下章节展示了Spring Boot、Quarkus和共享Java的具体示例,涵盖命名、不可变性、依赖注入、响应式代码、异常处理、项目布局、日志记录、配置和测试。

命名

// PASS:类/Records: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:[QUARKUS] JAX-RS资源命名为*Resource,而非*Controller
public class MarketResource {}

// PASS:[SPRING] REST控制器命名为*Controller
public class MarketController {}

不可变性

// PASS:优先使用records和final字段
public record MarketDto(Long id, String name, MarketStatus status) {}

public class Market {
  private final Long id;
  private final String name;
  // 仅提供getters,无setters
}

// PASS:[QUARKUS] Panache active-record实体使用public字段(Quarkus约定)
@Entity
public class Market extends PanacheEntity {
  public String name;
  public MarketStatus status;
  // Panache在构建时生成访问器;此处public字段是惯用做法
}

// PASS:[QUARKUS] Panache MongoDB实体
@MongoEntity(collection = "markets")
public class Market extends PanacheMongoEntity {
  public String name;
  public MarketStatus status;
}

Optional用法

// PASS:从find*方法返回Optional
// [SPRING]
Optional<Market> market = marketRepository.findBySlug(slug);

// [QUARKUS] Panache
Optional<Market> market = Market.find("slug", slug).firstResultOptional();

// PASS:使用map/flatMap而非get()
return market
    .map(MarketResponse::from)
    .orElseThrow(() -> new EntityNotFoundException("Market not found"));

Stream最佳实践

// PASS:使用Stream进行转换,保持管道简短
List<String> names = markets.stream()
    .map(Market::name)
    .filter(Objects::nonNull)
    .toList();

// FAIL:避免复杂的嵌套Stream;建议使用循环以提高清晰度

依赖注入

// PASS:[SPRING] 构造器注入(优先于@Autowired字段注入)
@Service
public class MarketService {
  private final MarketRepository marketRepository;

  public MarketService(MarketRepository marketRepository) {
    this.marketRepository = marketRepository;
  }
}

// PASS:[QUARKUS] 构造器注入
@ApplicationScoped
public class MarketService {
  private final MarketRepository marketRepository;

  @Inject
  public MarketService(MarketRepository marketRepository) {
    this.marketRepository = marketRepository;
  }
}

// PASS:[QUARKUS] 包私有字段注入(在Quarkus中可接受——避免代理问题)
@ApplicationScoped
public class MarketService {
  @Inject
  MarketRepository marketRepository;
}

// FAIL:[SPRING] 使用@Autowired的字段注入
@Autowired
private MarketRepository marketRepository; // 使用构造器注入

// FAIL:[QUARKUS] 需要拦截或延迟初始化时使用@Singleton
@Singleton // 不可代理——改用@ApplicationScoped
public class MarketService {}

响应式模式 [QUARKUS]

// PASS:从响应式端点返回Uni/Multi
@GET
@Path("/{slug}")
public Uni<Market> findBySlug(@PathParam("slug") String slug) {
  return Market.find("slug", slug)
      .<Market>firstResult()
      .onItem().ifNull().failWith(() -> new MarketNotFoundException(slug));
}

// PASS:非阻塞管道组合
public Uni<OrderConfirmation> placeOrder(OrderRequest req) {
  return validateOrder(req)
      .chain(valid -> persistOrder(valid))
      .chain(order -> notifyFulfillment(order));
}

// FAIL:在Uni/Multi管道内进行阻塞调用
public Uni<Market> find(String slug) {
  Market m = Market.find("slug", slug).firstResult(); // 阻塞——破坏事件循环
  return Uni.createFrom().item(m);
}

// FAIL:对共享Uni进行多次订阅
Uni<Market> shared = fetchMarket(slug);
shared.subscribe().with(m -> log(m));
shared.subscribe().with(m -> cache(m)); // 双重订阅——使用Uni.memoize()

异常处理

  • 对领域错误使用非受检异常;为技术异常添加上下文
  • 创建领域特定异常(例如MarketNotFoundException)
  • 避免宽泛的catch (Exception ex),除非集中重新抛出/记录日志
throw new MarketNotFoundException(slug);

集中式异常处理

// [SPRING]
@RestControllerAdvice
public class GlobalExceptionHandler {
  @ExceptionHandler(MarketNotFoundException.class)
  public ResponseEntity<ErrorResponse> handle(MarketNotFoundException ex) {
    return ResponseEntity.status(404).body(ErrorResponse.from(ex));
  }
}

// [QUARKUS] 选项A:ExceptionMapper
@Provider
public class MarketNotFoundMapper implements ExceptionMapper<MarketNotFoundException> {
  @Override
  public Response toResponse(MarketNotFoundException ex) {
    return Response.status(404).entity(ErrorResponse.from(ex)).build();
  }
}

// [QUARKUS] 选项B:@ServerExceptionMapper(RESTEasy Reactive)
@ServerExceptionMapper
public RestResponse<ErrorResponse> handle(MarketNotFoundException ex) {
  return RestResponse.status(Status.NOT_FOUND, ErrorResponse.from(ex));
}

泛型和类型安全

  • 避免使用原始类型;声明泛型参数
  • 优先使用有界泛型实现可重用工具
public <T extends Identifiable> Map<Long, T> indexById(Collection<T> items) { ... }

项目结构

[SPRING] Maven/Gradle

src/main/java/com/example/app/
  config/
  controller/
  service/
  repository/
  domain/
  dto/
  util/
src/main/resources/
  application.yml
src/test/java/... (与main镜像)

[QUARKUS] Maven/Gradle

src/main/java/com/example/app/
  config/              # @ConfigMapping、@ConfigProperty Bean、Producers
  resource/            # JAX-RS资源(非"controller")
  service/
  repository/          # PanacheRepository实现(如果未使用active record)
  domain/              # JPA/Panache实体、MongoDB实体
  dto/
  util/
  mapper/              # MapStruct映射器(如果使用)
src/main/resources/
  application.properties   # Quarkus约定(通过quarkus-config-yaml支持YAML)
  import.sql               # Hibernate自动导入,用于开发/测试
src/test/java/... (与main镜像)

格式化与样式

  • 一致使用2或4空格(项目标准)
  • 每个文件一个公共顶层类型
  • 保持方法简短且专注;提取辅助方法
  • 成员顺序:常量、字段、构造器、公有方法、protected、private

应避免的代码坏味道

  • 长参数列表 → 使用DTO或建造者模式
  • 深层嵌套 → 提前返回
  • 魔法数字 → 命名常量
  • 静态可变状态 → 优先使用依赖注入
  • 静默catch块 → 记录日志并操作或重新抛出
  • [QUARKUS]:@Singleton误用为@ApplicationScoped——破坏代理和拦截
  • [QUARKUS]:混合使用quarkus-resteasy-reactive和quarkus-resteasy(经典版)——选择一个栈
  • [QUARKUS]:在同一个有界上下文中同时使用Panache active-record和repository模式——选其一

日志记录

// [SPRING] SLF4J
private static final Logger log = LoggerFactory.getLogger(MarketService.class);
log.info("fetch_market slug={}", slug);
log.error("failed_fetch_market slug={}", slug, ex);

// [QUARKUS] JBoss Logging(默认,构建时零成本)
private static final Logger log = Logger.getLogger(MarketService.class);
log.infof("fetch_market slug=%s", slug);
log.errorf(ex, "failed_fetch_market slug=%s", slug);

// [QUARKUS] 备选:简化日志记录,使用@Inject
@Inject
Logger log; // CDI注入,作用于声明类

Null处理

  • 仅在不可避免时接受@Nullable;否则使用@NonNull
  • 对输入参数使用Bean Validation(@NotNull、@NotBlank)
  • [QUARKUS]:在@BeanParam、@RestForm和请求体参数上应用@Valid

配置

// [SPRING] @ConfigurationProperties
@ConfigurationProperties(prefix = "market")
public record MarketProperties(int maxPageSize, Duration cacheTtl) {}

// [QUARKUS] @ConfigMapping(类型安全,构建时验证)
@ConfigMapping(prefix = "market")
public interface MarketConfig {
  int maxPageSize();
  Duration cacheTtl();
}

// [QUARKUS] 使用@ConfigProperty获取简单值
@ConfigProperty(name = "market.max-page-size", defaultValue = "100")
int maxPageSize;

测试期望

共享规范

  • JUnit 5 + AssertJ用于流式断言
  • Mockito用于模拟;尽可能避免部分模拟
  • 优先使用确定性测试;不隐藏sleep

[SPRING]

  • @WebMvcTest用于控制器切片,@DataJpaTest用于仓库切片
  • @SpringBootTest保留用于完整集成测试
  • @MockBean用于替换Spring上下文中的Bean

[QUARKUS]

  • 普通JUnit 5 + Mockito用于单元测试(无需@QuarkusTest)
  • @QuarkusTest保留用于CDI集成测试
  • @InjectMock用于替换CDI集成测试中的Bean
  • 数据库/Kafka/Redis使用Dev Services——如果Dev Services足够,避免手动Testcontainers配置
  • @QuarkusTestResource用于自定义外部服务生命周期
// [SPRING] 控制器测试
@WebMvcTest(MarketController.class)
class MarketControllerTest {
  @Autowired MockMvc mockMvc;
  @MockBean MarketService marketService;
}

// [QUARKUS] 集成测试
@QuarkusTest
class MarketResourceTest {
  @InjectMock
  MarketService marketService;

  @Test
  void should_return_404_when_market_not_found() {
    given().when().get("/markets/unknown").then().statusCode(404);
  }
}

// [QUARKUS] 单元测试(无CDI,无@QuarkusTest)
@ExtendWith(MockitoExtension.class)
class MarketServiceTest {
  @Mock MarketRepository marketRepository;
  @InjectMocks MarketService marketService;
}

请记住:保持代码有意、有类型且可观察。优先考虑可维护性,而不是微观优化,除非已证明有必要。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

相关技能