원클릭으로
java-code-review
Comprehensive Java code quality checklist covering correctness, security, performance, and maintainability
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Comprehensive Java code quality checklist covering correctness, security, performance, and maintainability
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Use when implementing Spring Boot 3.x applications. Provides hands-on implementation patterns for web, data, security, testing, and cloud-native development.
Review REST API contracts for HTTP semantics, versioning, backward compatibility, and response consistency. Use when user asks "review API", "check endpoints", "REST review", or before releasing API changes.
Use when designing Spring Boot 3.x application architecture, making technology decisions, or planning project structure. Provides architectural patterns and references for project setup, JPA, security, testing, and reactive programming.
Use when designing, reviewing, or modifying REST API endpoints to enforce proper HTTP verbs, status codes, versioning, and API contract best practices.
Use when reviewing or writing code to enforce DRY, KISS, and YAGNI principles with Java-specific guidance.
Use when implementing or reviewing code that benefits from established design patterns like Builder, Factory, Strategy, Observer, Decorator, or Adapter.
| name | java-code-review |
| description | Comprehensive Java code quality checklist covering correctness, security, performance, and maintainability |
// BAD: potential NPE
String name = user.getAddress().getCity().getName();
// GOOD: use Optional or null checks
String name = Optional.ofNullable(user)
.map(User::getAddress)
.map(Address::getCity)
.map(City::getName)
.orElse("Unknown");
// BAD: inconsistent equals/hashCode
@Entity
public class Product {
@Id
private Long id;
private String sku;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Product p)) return false;
return Objects.equals(id, p.id); // null id before persist
}
}
// GOOD: use business key
@Entity
public class Product {
@Id @GeneratedValue
private Long id;
@NaturalId
private String sku;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Product p)) return false;
return Objects.equals(sku, p.sku);
}
@Override
public int hashCode() {
return Objects.hash(sku);
}
}
// BAD: resource leak
InputStream is = new FileInputStream(file);
// process...
// GOOD: try-with-resources
try (var is = new FileInputStream(file);
var reader = new BufferedReader(new InputStreamReader(is))) {
return reader.lines().collect(Collectors.joining("\n"));
}
// BAD: ConcurrentModificationException risk
for (var item : items) {
if (item.isExpired()) {
items.remove(item);
}
}
// GOOD: use removeIf or stream
items.removeIf(Item::isExpired);
// or collect to new list
var activeItems = items.stream()
.filter(item -> !item.isExpired())
.toList();
// BAD: SQL injection
@Query("SELECT u FROM User u WHERE u.role = '" + role + "'")
List<User> findByRole(String role);
// GOOD: parameterized
@Query("SELECT u FROM User u WHERE u.role = :role")
List<User> findByRole(@Param("role") String role);
// BAD: logging sensitive data
log.info("User login: email={}, password={}", email, password);
// GOOD: mask or exclude sensitive fields
log.info("User login: email={}", maskEmail(email));
// BAD: returning sensitive fields in DTO
public record UserDto(String id, String email, String passwordHash) {}
// GOOD: exclude sensitive fields
public record UserDto(String id, String email, Instant lastLogin) {}
// BAD: multiple stream passes
long count = items.stream().filter(predicate).count();
List<Item> filtered = items.stream().filter(predicate).toList();
// GOOD: single pass
var filtered = items.stream().filter(predicate).toList();
long count = filtered.size();
// BAD: string concatenation in loop
String result = "";
for (var item : items) {
result += item.getName() + ", ";
}
// GOOD: StringBuilder or String.join
String result = items.stream()
.map(Item::getName)
.collect(Collectors.joining(", "));
// BAD: default capacity with known size
var map = new HashMap<String, User>();
for (var user : users) { map.put(user.getId(), user); }
// GOOD: pre-sized collection
var map = new HashMap<String, User>(users.size() * 4 / 3 + 1);
// or better: use Collectors.toMap
var map = users.stream()
.collect(Collectors.toMap(User::getId, Function.identity()));
// BAD: field injection
@Service
public class OrderService {
@Autowired
private OrderRepository orderRepository;
}
// GOOD: constructor injection
@Service
@RequiredArgsConstructor
public class OrderService {
private final OrderRepository orderRepository;
}
// BAD: transaction too broad
@Transactional
public OrderDto createOrderAndNotify(CreateOrderRequest request) {
var order = processOrder(request);
sendEmail(order); // external call inside transaction
callWebhook(order); // another external call
return mapToDto(order);
}
// GOOD: narrow transaction, async for side effects
@Transactional
public OrderDto createOrder(CreateOrderRequest request) {
var order = processOrder(request);
eventPublisher.publishEvent(new OrderCreatedEvent(order.getId()));
return mapToDto(order);
}
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
@Async
public void onOrderCreated(OrderCreatedEvent event) {
sendEmail(event.orderId());
callWebhook(event.orderId());
}
PascalCase nouns (OrderService, PaymentGateway)camelCase verbs (findById, calculateTotal)UPPER_SNAKE_CASE (MAX_RETRY_COUNT)is/has/can/should prefix (isValid, hasPermission)// BAD
if (retryCount > 3) { /* ... */ }
Thread.sleep(5000);
// GOOD
private static final int MAX_RETRIES = 3;
private static final Duration RETRY_DELAY = Duration.ofSeconds(5);
if (retryCount > MAX_RETRIES) { /* ... */ }
Thread.sleep(RETRY_DELAY.toMillis());
## Summary
[1-2 sentence overview]
## Critical (must fix)
- [ ] Issue description with file:line reference
## Improvements (should fix)
- [ ] Issue description with suggested alternative
## Suggestions (nice to have)
- [ ] Minor improvement or style suggestion
## Positive
- Acknowledge good patterns found