java-coding-guideline

Use when writing, reviewing, or refactoring Java code to enforce baseline conventions for imports, nullability, immutability, exceptions, resource handling, naming, and concurrency.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "java-coding-guideline" with this command: npx skills add gabia/agent-skills/gabia-agent-skills-java-coding-guideline

Java Coding Guideline

CRITICAL: These rules apply to ALL Java code unless explicitly overridden by more specific skills.

Import Statements

Always use explicit imports without wildcards for better code clarity and maintainability.

✅ Do

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

❌ Don't

import static org.assertj.core.api.Assertions.*;

Vertical Spacing (Readability)

Use consistent vertical spacing inside classes to make diffs smaller and code easier to scan.

Rule

  • Insert exactly one blank line between:
    • field blocks and the next field block (when grouped)
    • fields and the first constructor
    • constructors and methods
    • methods and the next method
  • Also insert one blank line right after the opening { of a class (before the first field/initializer), unless the class is intentionally empty.

✅ Do

public final class SomeClass {

    @NonNull
    private final String fieldA;

    @NonNull
    private final String fieldB;

    public void someFunc() {
        // some action
    }

    public String getFieldA() {
        return fieldA;
    }
}

❌ Don't

public final class SomeClass {
    @NonNull
    private final String fieldA;
    @NonNull
    private final String fieldB;
    public void someFunc() {
        // some action
    }
    public String getFieldA() {
        return fieldA;
    }
}

Constructors

Use a single primary constructor and delegate auxiliary constructors using this().

✅ Do

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;
    }
}

❌ Don't

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 Usage

Avoid using Optional as return values or parameters. Use @Nullable annotations instead.

✅ Do

public final class SomeClass {

    @Nullable
    public Integer someNullable() {
        if (something) return null;
        return 1;
    }

    public void func(@Nullable Integer param) {
        // do something
    }
}

❌ Don't

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
    }
}

Wrapper vs Primitive Types

  • Use wrapper types when null is expected
  • Use primitive types when null should not occur

✅ Do

public 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;
    }
}

❌ Don't

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;
    }
}

Null Comparison

  • Use A == null for general cases
  • Use Objects.isNull for Stream API or functional programming contexts

✅ Do

final Integer someVariable = null;

if (someVariable == null) {
    // do something
}

List<Integer> lists = new ArrayList<>();
lists.stream()
  .filter(Objects::isNull)
  .collect(Collectors.toList());

❌ Don't

final Integer someVariable = null;

if (Objects.isNull(someVariable)) {
    // do something
}

List<Integer> lists = new ArrayList<>();
lists.stream()
  .filter(p -> p == null)
  .collect(Collectors.toList());

Nullability Annotations

  • Use JSpecify annotations
  • Apply @Nullable and @NonNull to all methods including private ones
  • Avoid class-level or package-level annotations (Lombok compatibility issues)

✅ Do

public 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";
    }
}

❌ Don't

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 Naming

Use all lowercase and numbers only, following Google Java Style Guide conventions.

✅ Do

package com.example.project.initscript;

❌ Don't

package com.example.project.initScript;

Static Factory Methods

Use only of naming convention. For multiple types, use format of<Postfix>.

✅ Do

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);
    }
}

❌ Don't

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);
    }
}

Resource Management

Always use try-with-resources for AutoCloseable resources. Never rely on finalizers.

Try-With-Resources

✅ Do

public 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);
    }
}

❌ Don't

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
    }
}

Composition over Inheritance

Prefer composition over inheritance.

✅ Do

public final class SomeFeature {
    public void func() { /* ... */ }
}

public final class SomeClass {

    private final SomeFeature feature;

    public void func2() {
        feature.func();
        // do something
    }
}

❌ Don't

public class SomeFeature {
    public void func() { /* ... */ }
}

public final class SomeClass extends SomeFeature {

    public void func2() {
        super.func();
        // do something
    }
}

Immutable Objects

All objects should use final keyword unless needed for extension or framework requirements.

✅ Do

public final class SomeClass {
    // ...
}

❌ Don't

public class SomeClass {
    // ...
}

Exception Catching

Catch only the minimum necessary exceptions.

✅ Do

try {
    // do something
} catch (IllegalArgumentException e) {
    // do catch
}

❌ Don't

try {
    // do something
} catch (RuntimeException e) {
    // do catch
}

Implementing AutoCloseable

When implementing AutoCloseable:

  1. Make close() idempotent (safe to call multiple times)
  2. Never throw exceptions from close() (suppressed exceptions problem)
  3. Log errors instead of throwing them

✅ Do

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);
        }
    }
}

❌ Don't

public final class DatabaseConnection implements AutoCloseable {

    @NonNull
    private final Connection connection;

    @Override
    public void close() throws SQLException {
        connection.close();  // Not idempotent; exception propagates
    }
}

Date/Time API

Use java.time (JSR-310) exclusively. java.util.Date and java.util.Calendar are banned in new code.

Type Selection

Use CaseTypeExample
Storage/transfer (UTC)InstantAPI timestamps, DB storage
User displayZonedDateTimeTime shown in UI
Date onlyLocalDateBirthdays, expiration dates
Time onlyLocalTimeBusiness hours, alarms
DurationDuration / PeriodElapsed time, date differences

✅ Do

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);
    }
}

Formatter reuse (thread-safe):

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() {}
}

❌ Don't

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);
    }
}

Legacy Interop (boundary only)

When interfacing with legacy APIs that require Date, convert at the boundary:

// Instant → Date (boundary layer only)
Date legacyDate = Date.from(instant);

// Date → Instant (convert immediately on receipt)
Instant instant = legacyDate.toInstant();

Additional Guidelines

Builder Pattern

Use Lombok-style builders for API consistency.

Variable and Method Naming

  • Use var keyword from JVM 10+
  • Use meaningful variable names
    • But avoid too long variable, function, field names
  • Method names should be verbs
  • Avoid using 'get' prefix except for getters

Camel Case Convention

Apply camel case to mixed-case words and abbreviations (e.g., "MultiNIC" becomes "MultiNic").

Control Flow Statements

Use one-liner syntax for simple if statements without braces.

✅ Do

if (someCondition) doSomething();

❌ Don't

if (someCondition) {
    doSomething();
}

Comments

  • Use comments only in special cases
  • TODO comments should be for immediate tasks
  • Avoid unnecessary comments that restate the code

See Also

Reference Guides

For deeper understanding of specific topics:

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

java-xmlrpc-guideline

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

vercel-react-best-practices

React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.

Repository Source
23K212.5K
vercel
Coding

svelte5-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review