Fundamentals 23 min read

How to Master Boilerplate Code in Java for Faster, Cleaner Development

This article explains what boilerplate code is, why it speeds up development, and provides practical Java examples and techniques—including annotations, design patterns, and immutable collections—to write, reuse, and reduce repetitive code while maintaining quality and readability.

Alibaba Cloud Developer
Alibaba Cloud Developer
Alibaba Cloud Developer
How to Master Boilerplate Code in Java for Faster, Cleaner Development

Preface

During the Qingli era, a commoner named Bi Sheng invented movable type printing using clay molds; printing a few copies was slow, but printing dozens or hundreds was extremely fast.

Just as movable type accelerated printing, reusable code snippets—called boilerplate code —let developers copy, paste, and modify standard patterns quickly, improving consistency, quality, and speed.

1. What Is Boilerplate Code?

Boilerplate code (also known as template code) refers to fixed‑pattern code blocks that can be widely applied across modules. For example, reading a file is a typical boilerplate:

try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
    String line;
    while (Objects.nonNull(line = reader.readLine())) {
        // process a line
        ...
    }
} catch (IOException e) {
    String message = String.format("Read file (%s) error", fileName);
    log.error(message, e);
    throw new ExampleException(message, e);
}

2. Benefits of Boilerplate Code

Provides a standard example for newcomers to learn and start quickly.

Offers a ready‑made solution for similar cases.

Helps accumulate experience and continuously optimise the pattern.

Improves code quality because the pattern has been battle‑tested.

Boosts coding speed by copy‑paste‑modify workflow.

Ensures uniform coding style across the team.

3. How to Write Boilerplate Code

Common methods include:

Copy‑paste generation.

Text‑replace generation.

Excel‑formula generation.

IDE tools or plugins (e.g., generate constructors, getters/setters, toString, DAO methods).

Code‑generation scripts.

4. Reducing Boilerplate Code

Using Annotations

In JavaBeans, Lombok’s @Getter / @Setter can eliminate repetitive accessor methods:

public class User {
    private Long id;
    // getters and setters generated by Lombok
}

Using Frameworks

MyBatis abstracts JDBC boilerplate by mapping interfaces to SQL statements:

@Mapper
public interface UserDAO {
    List<EmployeeDO> queryEmployee(@Param("companyId") Long companyId);
}
<mapper namespace="com.example.repository.UserDAO">
    <select id="queryEmployee" resultType="com.example.repository.UserDO">
        SELECT id, name FROM t_user WHERE company_id = #{companyId}
    </select>
</mapper>

Using Design Patterns

Encapsulate repetitive logic with patterns such as Template Method:

public static void readLine(String fileName, Consumer<String> lineConsumer) {
    try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
        String line;
        while (Objects.nonNull(line = reader.readLine())) {
            lineConsumer.accept(line);
        }
    } catch (IOException e) {
        String message = String.format("Read file (%s) error", fileName);
        log.error(message, e);
        throw new ExampleException(message, e);
    }
}

5. Best Practices for Utility Classes

Define constants and helper methods in a final class with a private constructor to prevent instantiation and inheritance:

/** Example utility class */
public final class ExampleHelper {
    public static final int CONST_VALUE = 123;
    private ExampleHelper() { throw new UnsupportedOperationException(); }
    public static int sum(int a, int b) { return a + b; }
}

Follow the static final order for constants (static before final) as recommended by the Java language spec.

6. Defining Enums Properly

Make enum fields private final and provide getters. Avoid mutable fields:

public enum ExampleEnum {
    ONE(1, "one(1)"),
    TWO(2, "two(2)"),
    THREE(3, "three(3)");
    private final int value;
    private final String desc;
    ExampleEnum(int value, String desc) { this.value = value; this.desc = desc; }
    public int getValue() { return value; }
    public String getDesc() { return desc; }
}

7. Model Class Definitions

Three common approaches for a User model (id, name, age, desc):

JavaBean : private fields, public getters/setters, no‑arg constructor.

Overloaded Constructors : multiple constructors for required/optional fields; can be immutable.

Builder Pattern : static newBuilder method, chainable setters, immutable result.

// Builder usage
User user = User.newBuilder(1L, "alibaba").age(102).desc("test").build();

8. Defining Collection Constants

Use Collections.unmodifiable* to create truly immutable constants:

public final class ExampleHelper {
    public static final List<Integer> CONST_VALUE_LIST =
        Collections.unmodifiableList(Arrays.asList(1, 2, 3));
    public static final Set<Integer> CONST_VALUE_SET =
        Collections.unmodifiableSet(new HashSet<>(Arrays.asList(1, 2, 3)));
    public static final Map<Integer, String> CONST_VALUE_MAP;
    static {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "value1");
        map.put(2, "value2");
        map.put(3, "value3");
        CONST_VALUE_MAP = Collections.unmodifiableMap(map);
    }
}

9. Defining Array Constants

Expose a cloned copy to keep the original immutable:

private static final int[] CONST_VALUES = new int[] {1, 2, 3};
public static int[] getConstValues() { return CONST_VALUES.clone(); }

10. Reducing Complex Conditional Logic

Instead of a long && chain, store predicates in an immutable list and evaluate them:

private static final List<Predicate<AuditDataVO>> AUDIT_PREDICATES =
    Collections.unmodifiableList(Arrays.asList(
        data -> isPassed(data.getAuditItem1()),
        data -> isPassed(data.getAuditItem2()),
        // ...
        data -> isPassed(data.getAuditItem11())
    ));

private static AuditResult getAuditResult(AuditDataVO data) {
    for (Predicate<AuditDataVO> p : AUDIT_PREDICATES) {
        if (!p.test(data)) return AuditResult.REJECTED;
    }
    return AuditResult.PASSED;
}

These techniques lower cyclomatic complexity and improve maintainability.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Design PatternsJavaCode Refactoringbest practicesBoilerplate Code
Alibaba Cloud Developer
Written by

Alibaba Cloud Developer

Alibaba's official tech channel, featuring all of its technology innovations.

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.