Best Practices for Writing High‑Quality Java Methods

This article discusses how to write clean, maintainable Java methods by covering proper method signatures, limiting parameters, avoiding varargs misuse, validating inputs, minimizing side effects, handling exceptions correctly, writing concise method bodies, and providing effective logging and documentation practices.

JD Tech
JD Tech
JD Tech
Best Practices for Writing High‑Quality Java Methods

What Makes a Good Method

A good Java method should have a single, clear responsibility, be easy for teammates to read and maintain, and follow consistent coding standards such as those from Effective Java, Clean Code, and JD.com Java guidelines.

Method Signature and Parameters (Input)

Keep the number of parameters low – ideally none, one, or at most three. If more parameters are needed, encapsulate them in a dedicated parameter object to avoid confusion and reduce the chance of ordering errors.

public void calculateShippingCost(ShippingDetails details) {
    // shipping calculation logic
}

public class ShippingDetails {
    private double weight;
    private double volume;
    private double length;
    private double width;
    private double height;
    private String destination;
    // constructors, getters, setters omitted
}

Incorrect example with many primitive parameters demonstrates how easy it is to swap the order of similar‑type arguments, leading to bugs.

public void calculateShippingCost(double weight, double volume, double length,
                                 double width, double height, String destination) {
    // shipping calculation logic
}

// Wrong call – weight and volume swapped
service.calculateShippingCost(30.0, 50.0, 10.0, 5.0, 3.0, "New York");

// Correct call
service.calculateShippingCost(50.0, 30.0, 10.0, 5.0, 3.0, "New York");

Varargs Usage

Varargs create a new array on each call, which can be a performance problem in hot loops. Prefer explicit collections or overloads when performance matters.

// Bad – varargs in a tight loop
for (int i = 0; i < 1_000_000; i++) {
    logger.log("INFO", "Message", "number", String.valueOf(i));
}

// Better – pass a List
for (int i = 0; i < 1_000_000; i++) {
    logger.log("INFO", List.of("Message", "number", String.valueOf(i)));
}

// Best – avoid collection creation entirely
for (int i = 0; i < 1_000_000; i++) {
    logger.log("INFO", "Message", "number", String.valueOf(i));
}

Input Validation

Validate arguments at the start of the method and clearly document constraints in the API. Early validation prevents downstream errors and makes debugging easier.

public void saveUser(String userName) {
    if (userName == null || userName.length() > 20) {
        throw new IllegalArgumentException("User name cannot be null and must be less than 20 characters");
    }
    saveToDatabase(userName);
}

private void saveToDatabase(String userName) {
    // database persistence logic
}

Method Body Size

Keep methods short – many coding standards (e.g., Alibaba, JD) recommend no more than 70‑80 lines. Focus on a single responsibility and extract reusable logic into helper methods.

Side Effects

A method should avoid hidden side effects such as mutating input objects or global state. If a method must produce additional results, return a composite object instead of modifying parameters.

public FilterResultAndResponse filterBusinessType(String logPrefix, Request request) {
    int result = /* filtering logic */;
    Response response = new Response();
    response.setFilteredData(/* ... */);
    return new FilterResultAndResponse(result, response);
}

class FilterResultAndResponse {
    private int filterResult;
    private Response response;
    public FilterResultAndResponse(int filterResult, Response response) {
        this.filterResult = filterResult;
        this.response = response;
    }
    // getters and setters
}

Exception Handling

Use exceptions only for truly exceptional situations, not for normal control flow. Do not swallow exceptions with empty catch blocks; always log or re‑throw with meaningful context.

// Bad – using exception for flow control
public static int parseNumber(String number) {
    try {
        return Integer.parseInt(number);
    } catch (NumberFormatException e) {
        throw e;
    }
}

// Good – regular control structure
public static boolean isNumeric(String str) {
    if (str == null) return false;
    try {
        Integer.parseInt(str);
        return true;
    } catch (NumberFormatException e) {
        return false;
    }
}

Logging Guidelines

Log with accuracy, clarity, and minimal volume. Include a traceId, use a mix of Chinese description and code identifiers for readability, and log input/output parameters for external APIs.

Documentation and Comments

Provide detailed method comments that describe the contract, pre‑conditions, post‑conditions, and any side effects. Keep comments up‑to‑date; stale comments can be more harmful than none.

/**
 * Returns the business type and may modify the provided response.
 * Caller must inspect the response after the call.
 */
public int filterBusinessType(Request request, Response response) {
    boolean flag = isXXX(request, response);
    // ...
}

Overall, adhering to these practices improves code readability, maintainability, and reduces bugs in Java projects.

Javaexception-handlingbest practicesloggingcode qualitymethod design
JD Tech
Written by

JD Tech

Official JD technology sharing platform. All the cutting‑edge JD tech, innovative insights, and open‑source solutions you’re looking for, all in one place.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.