Loading...
Loading...
Use when writing, reviewing, or refactoring Java code to enforce baseline conventions for imports, nullability, immutability, exceptions, resource handling, naming, and concurrency.
npx skill4agent add gabia/agent-skills java-coding-guidelineimport static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;import static org.assertj.core.api.Assertions.*;{public final class SomeClass {
@NonNull
private final String fieldA;
@NonNull
private final String fieldB;
public void someFunc() {
// some action
}
public String getFieldA() {
return fieldA;
}
}public final class SomeClass {
@NonNull
private final String fieldA;
@NonNull
private final String fieldB;
public void someFunc() {
// some action
}
public String getFieldA() {
return fieldA;
}
}this()public final class SomeClass {
private final int field1;
private final int field2;
public SomeClass() {
this(1, 2);
}
public SomeClass(int field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
}public final class SomeClass {
private final int field1;
private final int field2;
public SomeClass() {
this.field1 = 1;
this.field2 = 2;
}
public SomeClass(int field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
}Optional@Nullablepublic final class SomeClass {
@Nullable
public Integer someNullable() {
if (something) return null;
return 1;
}
public void func(@Nullable Integer param) {
// do something
}
}public final class SomeClass {
@NonNull
public Optional<Integer> someNullable() {
if (something) return Optional.ofNullable(null);
return Optional.ofNullable(1);
}
public void func(@NonNull Optional<Integer> param) {
// do something
}
}nullnullpublic final class SomeClass {
private final int field1;
@Nullable
private final Long field2;
public SomeClass(int field1, @Nullable Long field2) {
this.field1 = field1;
this.field2 = field2;
}
}public final class SomeClass {
@NonNull
private final Integer field1;
@Nullable
private final Long field2;
public SomeClass(@NonNull Integer field1, @Nullable Long field2) {
this.field1 = field1;
this.field2 = field2;
}
}A == nullObjects.isNullfinal Integer someVariable = null;
if (someVariable == null) {
// do something
}
List<Integer> lists = new ArrayList<>();
lists.stream()
.filter(Objects::isNull)
.collect(Collectors.toList());final Integer someVariable = null;
if (Objects.isNull(someVariable)) {
// do something
}
List<Integer> lists = new ArrayList<>();
lists.stream()
.filter(p -> p == null)
.collect(Collectors.toList());@Nullable@NonNullpublic final class SomeClass {
@Nullable
private final Integer field1;
@NonNull
private final String field2;
@NonNull
public String func() {
return process();
}
@Nullable
private String process() {
if (field1 == null) return null;
return "awesome";
}
}public final class SomeClass {
private final Integer field1;
private final String field2;
public String func() {
return process();
}
private String process() {
if (field1 == null) return null;
return "awesome";
}
}package com.example.project.initscript;package com.example.project.initScript;ofof<Postfix>public final class SomeClass {
private final int field1;
private SomeClass(int field1) {
this.field1 = field1;
}
public static SomeClass ofDefault() {
return new SomeClass(1);
}
public static SomeClass ofSpecial() {
return new SomeClass(2);
}
}public final class SomeClass {
private final int field1;
private SomeClass(int field1) {
this.field1 = field1;
}
public static SomeClass from() {
return new SomeClass(1);
}
public static SomeClass valueOf() {
return new SomeClass(2);
}
}AutoCloseablepublic String readFile(@NonNull Path path) throws IOException {
try (var reader = Files.newBufferedReader(path)) {
return reader.lines().collect(Collectors.joining("\n"));
}
}
// Multiple resources
public void copyStream(@NonNull InputStream in, @NonNull OutputStream out) throws IOException {
try (in; out) { // Java 9+: can use already-declared variables
in.transferTo(out);
}
}public String readFile(@NonNull Path path) throws IOException {
BufferedReader reader = Files.newBufferedReader(path);
try {
return reader.lines().collect(Collectors.joining("\n"));
} finally {
reader.close(); // The original exception may be suppressed if one occurs here
}
}public final class SomeFeature {
public void func() { /* ... */ }
}
public final class SomeClass {
private final SomeFeature feature;
public void func2() {
feature.func();
// do something
}
}public class SomeFeature {
public void func() { /* ... */ }
}
public final class SomeClass extends SomeFeature {
public void func2() {
super.func();
// do something
}
}finalpublic final class SomeClass {
// ...
}public class SomeClass {
// ...
}try {
// do something
} catch (IllegalArgumentException e) {
// do catch
}try {
// do something
} catch (RuntimeException e) {
// do catch
}AutoCloseableclose()close()public final class DatabaseConnection implements AutoCloseable {
@NonNull
private final Connection connection;
private volatile boolean closed = false;
@Override
public void close() {
if (closed) return; // Idempotent: safe to call multiple times
closed = true;
try {
connection.close();
} catch (SQLException e) {
// Log only; do not throw (exceptions in close can suppress the original)
logger.warn("Failed to close connection", e);
}
}
}public final class DatabaseConnection implements AutoCloseable {
@NonNull
private final Connection connection;
@Override
public void close() throws SQLException {
connection.close(); // Not idempotent; exception propagates
}
}java.timejava.util.Datejava.util.Calendar| Use Case | Type | Example |
|---|---|---|
| Storage/transfer (UTC) | | API timestamps, DB storage |
| User display | | Time shown in UI |
| Date only | | Birthdays, expiration dates |
| Time only | | Business hours, alarms |
| Duration | | Elapsed time, date differences |
public final class Event {
@NonNull
private final Instant createdAt; // UTC timestamp
@NonNull
private final LocalDate eventDate; // Date only
@NonNull
private final ZoneId timeZone; // Display time zone
@NonNull
public ZonedDateTime displayTime() {
return createdAt.atZone(timeZone);
}
}public final class DateFormats {
// DateTimeFormatter is thread-safe, so reuse as constants
public static final DateTimeFormatter ISO_DATE = DateTimeFormatter.ISO_LOCAL_DATE;
public static final DateTimeFormatter ENGLISH_DATE = DateTimeFormatter.ofPattern("MMM dd, yyyy");
private DateFormats() {}
}public final class Event {
@NonNull
private final Date createdAt; // Do not use java.util.Date
@NonNull
private final Calendar calendar; // Do not use java.util.Calendar
@NonNull
public String format() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // Not thread-safe
return sdf.format(createdAt);
}
}Date// Instant → Date (boundary layer only)
Date legacyDate = Date.from(instant);
// Date → Instant (convert immediately on receipt)
Instant instant = legacyDate.toInstant();varif (someCondition) doSomething();if (someCondition) {
doSomething();
}