mcpField
J
java

java

github.com/claude-dev-suite开发4643 次安装4 天前更新
代码仓库

关于 java

面向开发者的 Java 核心知识技能,通过示例涵盖现代语言特性、编码模式、代码质量检查和生产就绪实践。还整理静态分析工具、测试、错误处理、性能与故障排查内容。

主要功能

  1. 01现代 Java 语言示例
  2. 02集合与 Stream 模式
  3. 03静态分析和风格指南
  4. 04生产就绪实践
  5. 05测试与性能指导
  6. 06常见错误排查

适用场景

  1. 01查阅现代 Java 编码模式
  2. 02选择静态分析规则
  3. 03为服务上线做准备
  4. 04排查常见 Java 运行时问题

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill java

安装后在 Claude Code 中输入/java确认已加载。

详细介绍

Java 核心知识

Java 现代特性(17+)

// Records (immutable data classes)
public record User(Long id, String name, String email) {}

// Sealed classes
public sealed interface Shape permits Circle, Rectangle {}
public final class Circle implements Shape { }
public final class Rectangle implements Shape { }

// Pattern matching for instanceof
if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

// Switch expressions
String result = switch (status) {
    case ACTIVE -> "Active";
    case INACTIVE -> "Inactive";
    default -> "Unknown";
};

// Text blocks
String json = """
    {
        "name": "John",
        "age": 30
    }
    """;

集合与流

// Stream operations
List<String> names = users.stream()
    .filter(u -> u.isActive())
    .map(User::getName)
    .sorted()
    .collect(Collectors.toList());

// Grouping
Map<Status, List<User>> byStatus = users.stream()
    .collect(Collectors.groupingBy(User::getStatus));

// Optional handling
Optional<User> user = findById(id);
String name = user.map(User::getName).orElse("Unknown");

常见模式

// Builder pattern
User user = User.builder()
    .name("John")
    .email("[email protected]")
    .build();

// Factory method
public static User of(String name, String email) {
    return new User(null, name, email);
}

// Dependency Injection (constructor)
@Service
public class UserService {
    private final UserRepository repository;

    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

异常处理

// Custom exception
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(Long id) {
        super("User not found: " + id);
    }
}

// Try-with-resources
try (var reader = new BufferedReader(new FileReader(file))) {
    return reader.lines().collect(Collectors.toList());
}

静态分析与代码检查

官方规则参考
工具规则数量文档
SonarJava733https://rules.sonarsource.com/java/
Checkstyle200+https://checkstyle.org/checks.html
PMD400+https://pmd.github.io/latest/pmd_rules_java.html
SpotBugs400+https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html
风格指南
指南链接
Google Java Stylehttps://google.github.io/styleguide/javaguide.html
Oracle Code Conventionshttps://www.oracle.com/java/technologies/javase/codeconventions-contents.html
主要规则类别

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <configLocation>google_checks.xml</configLocation>
    </configuration>
</plugin>
建议启用的关键规则
类别规则工具
BugNullPointerException 风险SonarJava S2259
Bug资源泄漏SonarJava S2095
安全SQL 注入SonarJava S3649
安全硬编码凭据SonarJava S2068
可维护性认知复杂度SonarJava S3776
可维护性参数过多Checkstyle

生产就绪性

错误处理
// Custom exception hierarchy
public abstract class BaseException extends RuntimeException {
    private final String errorCode;
    private final int httpStatus;

    protected BaseException(String message, String errorCode, int httpStatus) {
        super(message);
        this.errorCode = errorCode;
        this.httpStatus = httpStatus;
    }

    public String getErrorCode() { return errorCode; }
    public int getHttpStatus() { return httpStatus; }
}

public class EntityNotFoundException extends BaseException {
    public EntityNotFoundException(String entity, Object id) {
        super(
            String.format("%s not found with id: %s", entity, id),
            "NOT_FOUND",
            404
        );
    }
}

// Global exception handler
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(BaseException.class)
    public ResponseEntity<ErrorResponse> handleBaseException(BaseException ex) {
        log.warn("Business error: {}", ex.getMessage());
        return ResponseEntity
            .status(ex.getHttpStatus())
            .body(new ErrorResponse(ex.getErrorCode(), ex.getMessage()));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleUnexpected(Exception ex) {
        log.error("Unexpected error", ex);
        return ResponseEntity
            .status(500)
            .body(new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred"));
    }
}
空值安全
// Use Optional properly
public Optional<User> findById(Long id) {
    return repository.findById(id);
}

// Never return null from Optional
public User getById(Long id) {
    return findById(id)
        .orElseThrow(() -> new EntityNotFoundException("User", id));
}

// Use @Nullable and @NonNull annotations
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

public User updateUser(@NonNull Long id, @Nullable String email) {
    User user = getById(id);
    if (email != null) {
        user.setEmail(email);
    }
    return repository.save(user);
}

// Validation
import jakarta.validation.constraints.*;

public record CreateUserRequest(
    @NotBlank @Size(min = 2, max = 100) String name,
    @NotBlank @Email String email,
    @NotNull @Min(0) Integer age
) {}
日志记录
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

@Service
public class UserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    public User createUser(CreateUserRequest request) {
        MDC.put("operation", "createUser");
        MDC.put("email", request.email());

        log.info("Creating user");

        try {
            User user = userRepository.save(User.from(request));
            log.info("User created successfully: {}", user.getId());
            return user;
        } catch (Exception e) {
            log.error("Failed to create user", e);
            throw e;
        } finally {
            MDC.clear();
        }
    }
}
测试
// Unit test with Mockito
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock
    private UserRepository repository;

    @InjectMocks
    private UserService service;

    @Test
    void shouldCreateUser() {
        // Given
        var request = new CreateUserRequest("John", "[email protected]", 30);
        var expected = new User(1L, "John", "[email protected]", 30);
        when(repository.save(any())).thenReturn(expected);

        // When
        var result = service.createUser(request);

        // Then
        assertThat(result).isEqualTo(expected);
        verify(repository).save(any());
    }

    @Test
    void shouldThrowWhenUserNotFound() {
        // Given
        when(repository.findById(1L)).thenReturn(Optional.empty());

        // When/Then
        assertThatThrownBy(() -> service.getById(1L))
            .isInstanceOf(EntityNotFoundException.class)
            .hasMessageContaining("User not found");
    }
}

// Integration test
@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class UserControllerIT {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldCreateUser() throws Exception {
        mockMvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content("""
                    {"name": "John", "email": "[email protected]", "age": 30}
                    """))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id").exists());
    }
}
性能
// Connection pooling (HikariCP)
// application.yml
spring:
  datasource:
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000

// Caching
@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
    return repository.findById(id).orElseThrow();
}

@CacheEvict(value = "users", key = "#user.id")
public User save(User user) {
    return repository.save(user);
}
监控指标
指标目标
测试覆盖率> 80%
圈复杂度< 10
SonarQube Bug 数0
安全漏洞数0
检查清单
  • 自定义异常层次结构
  • 全局异常处理器
  • 对 DTO 进行 Bean 验证
  • 对可能返回空值的返回值使用 Optional
  • @NonNull/@Nullable 注解
  • 使用 MDC 的结构化日志记录
  • 使用 Mockito 编写单元测试
  • 使用 Testcontainers 编写集成测试
  • 配置连接池
  • 为热点数据添加缓存

不适合使用此技能的情况

场景改用
Spring Boot 框架backend-spring-boot skill
Lombok 注解lombok skill
MapStruct 映射mapstruct skill
JPA/HibernateORM 专用技能
使用 JUnit 进行测试testing-junit skill

反模式

反模式不良影响正确做法
返回 nullNullPointerException使用 Optional
捕获通用 Exception隐藏具体错误捕获具体异常
不关闭资源资源泄漏使用 try-with-resources
可变静态字段线程安全问题使用不可变对象或同步机制
在循环中拼接字符串O(n²) 性能开销使用 StringBuilder
空 catch 块静默失败记录日志或重新抛出
对字符串使用 ==比较引用使用 .equals()
不重写 equals/hashCode集合行为异常两者都重写,或都不重写

快速故障排除

问题原因解决方案
NullPointerException访问空引用检查是否为空,使用 Optional
ClassCastException类型转换错误转换前使用 instanceof
ConcurrentModificationException迭代时修改集合使用 Iterator.remove()
OutOfMemoryError堆内存耗尽增大堆内存,修复内存泄漏
StackOverflowError无限递归添加基例,或改用迭代
"Cannot find symbol"编译错误检查导入语句和拼写
死锁锁依赖形成循环采用一致的加锁顺序
资源泄漏未关闭流使用 try-with-resources

参考文档

评论

支持 Markdown