
java-lombok
by JongminChung
Systematic notes and summaries from my computer engineering studies.
SKILL.md
name: java-lombok description: Lombok patterns including @Delegate, @Builder, @Value, @UtilityClass for reducing boilerplate allowed-tools: [Read, Edit, Write, Bash, Grep, Glob]
Java Lombok Skill
Lombok standards for reducing boilerplate code while maintaining code quality and testability.
Prerequisites
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
Required Imports
// Lombok Core
import lombok.Builder;
import lombok.Value;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
// Lombok Advanced
import lombok.Delegate;
import lombok.Singular;
import lombok.experimental.UtilityClass;
import lombok.Builder.Default;
Core Annotations
@Delegate - Delegation Over Inheritance
Use @Delegate for delegation patterns instead of inheritance:
// CORRECT - delegation with Lombok
public class CachedTokenValidator implements TokenValidator {
@Delegate
private final TokenValidator delegate;
private final Cache<String, ValidationResult> cache;
public CachedTokenValidator(TokenValidator delegate) {
this.delegate = delegate;
this.cache = CacheBuilder.newBuilder().build();
}
@Override
public ValidationResult validate(String token) {
return cache.get(token, () -> delegate.validate(token));
}
}
// WRONG - inheritance creates tight coupling
public class CachedTokenValidator extends BaseTokenValidator { }
Use @Delegate for: Interface composition, wrapping implementations, cross-cutting concerns (caching, logging, metrics), avoiding inheritance hierarchies.
@Builder - Complex Object Construction
Use @Builder for classes with multiple optional parameters:
@Value
@Builder(toBuilder = true)
public class TokenConfig {
String issuer;
String audience;
@Builder.Default
Duration validity = Duration.ofHours(1);
@Builder.Default
int clockSkewSeconds = 30;
@Singular
Set<String> requiredClaims;
}
// Usage
TokenConfig config = TokenConfig.builder()
.issuer("https://auth.example.com")
.audience("my-api")
.requiredClaim("sub") // @Singular generates add method
.requiredClaim("exp")
.build();
// Copy with modifications via toBuilder()
TokenConfig modified = config.toBuilder()
.validity(Duration.ofHours(2))
.build();
Use @Builder for: Classes with 3+ parameters, optional parameters, immutable configuration objects, DTOs with many fields.
@Value - Immutable Objects
Use @Value for immutable value objects and DTOs:
@Value
public class ValidationResult {
boolean valid;
List<String> errors;
Instant validatedAt;
}
// Usage
ValidationResult result = new ValidationResult(true, List.of(), Instant.now());
boolean isValid = result.isValid(); // Getter
@Value generates: all-args constructor, getters (no setters), equals/hashCode, toString, all fields private final.
Use @Value for: Immutable DTOs, value objects, API request/response objects, configuration data.
@Data - Mutable Objects (Use Sparingly)
@Data
public class UserPreferences {
private String theme;
private Locale locale;
private int pageSize;
}
Prefer @Value or records for immutability. Use @Data only when mutability is genuinely required.
@UtilityClass - Static Method Classes
@UtilityClass
public class TokenUtils {
public static String extractTokenId(String token) {
// Implementation
}
public static boolean isExpired(String token) {
// Implementation
}
}
Makes class final, constructor private, all methods static.
Records vs Lombok @Value
| Criteria | Use Records | Use Lombok @Value |
|---|---|---|
| Java version | Java 17+ | Java 11+ |
| Builder pattern | Not built-in | @Value + @Builder |
| Collection builders | Not available | @Singular |
| Pattern matching | Java 21+ | Not available |
| Project context | Minimal dependencies | Already using Lombok |
| Customization | Limited | More flexible |
// Simple case - prefer records (Java 17+)
public record User(String id, String name, String email) {}
// Complex case - use Lombok
@Value
@Builder
@JsonIgnoreProperties(ignoreUnknown = true)
public class ApiResponse {
@JsonProperty("user_id")
String userId;
String status;
@Singular
List<String> messages;
}
Migration guidance: See pm-dev-java:java-core skill for Lombok to records migration.
Combining Annotations
@Value
@Builder
public class SearchCriteria {
String query;
@Builder.Default
int maxResults = 100;
@Singular
Set<String> categories;
LocalDate startDate;
LocalDate endDate;
}
// Usage - only specify what differs from defaults
SearchCriteria criteria = SearchCriteria.builder()
.query("example")
.category("tech")
.category("java")
.build();
Logging: @Slf4j Prohibition
Do NOT use @Slf4j or similar logging annotations in CUI projects:
// WRONG - Do not use in CUI projects
@Slf4j
public class TokenValidator { }
// CORRECT - Use CuiLogger explicitly
public class TokenValidator {
private static final CuiLogger LOGGER = new CuiLogger(TokenValidator.class);
}
CUI projects use CuiLogger, not SLF4J. See pm-dev-java-cui:cui-logging for details.
Common Pitfalls
| Pitfall | Wrong | Correct |
|---|---|---|
| Overusing @Data | @Data for immutable objects | Use @Value |
| Missing defaults | Builder without @Builder.Default | Add defaults for optional fields |
| Wrong logger | @Slf4j in CUI projects | Use CuiLogger explicitly |
| No toBuilder | Immutable without copy method | @Builder(toBuilder = true) |
| Inheritance | extends BaseClass | @Delegate with composition |
Best Practices Summary
- Prefer immutability: Use
@Valueover@Data - Use @Builder for 3+ parameters: Avoid long constructors
- Provide @Builder.Default: For optional fields with sensible defaults
- Use @Singular for collections: Cleaner builder API
- Use @Delegate for composition: Avoid inheritance hierarchies
- Consider records (Java 17+): For simple data carriers
- Use @UtilityClass: For static-only classes
Quality Checklist
- @Value used for immutable objects
- @Builder used for classes with 3+ parameters
- @Delegate used instead of inheritance
- @Builder.Default provided for optional fields
- @Singular used for collection builders
- Records considered as alternative (Java 17+)
- No Lombok logging annotations (use CuiLogger)
- @Data used only when mutability required
- @UtilityClass used for utility classes
Related Skills
pm-dev-java:java-core- Core Java patterns, records migrationpm-dev-java:java-null-safety- Null safety with Lombok
Score
Total Score
Based on repository quality metrics
SKILL.mdファイルが含まれている
ライセンスが設定されている
100文字以上の説明がある
GitHub Stars 100以上
1ヶ月以内に更新
10回以上フォークされている
オープンIssueが50未満
プログラミング言語が設定されている
1つ以上のタグが設定されている
Reviews
Reviews coming soon


