Fundamentals 15 min read

Effective Java Practices: Builder Pattern, Object Creation, and Performance Optimizations

This article presents a collection of Java best‑practice guidelines—including using the Builder pattern for many constructor arguments, privatizing utility class constructors, minimizing object creation, avoiding finalizers, applying the Law of Demeter, preferring enums, and careful use of var‑args—to improve code readability, memory usage, and runtime performance.

Full-Stack Internet Architecture
Full-Stack Internet Architecture
Full-Stack Internet Architecture
Effective Java Practices: Builder Pattern, Object Creation, and Performance Optimizations

Below is a concise set of practical Java tips aimed at improving code quality, performance, and maintainability.

1. Too many constructor parameters – use the Builder pattern

When a class has five or more parameters, or when parameters are expected to grow, introduce a Builder to assemble the object step‑by‑step.

public class Computer {
    protected String mBoard;
    protected String mDisplay;
    protected String mOs;

    private Computer(Builder builder) {
        this.mOs = builder.mOs;
        this.mBoard = builder.mBoard;
        this.mDisplay = builder.mDisplay;
    }

    @Override
    public String toString() {
        return "Computer{" + "mBoard='" + mBoard + '\'' + ", mDisplay='" + mDisplay + '\'' + ", mOs='" + mOs + '\'' + '}';
    }

    static class Builder {
        protected String mBoard;
        protected String mDisplay;
        protected String mOs;

        public Builder setmOs(String mOs) { this.mOs = mOs; return this; }
        public Builder setmBoard(String mBoard) { this.mBoard = mBoard; return this; }
        public Builder setmDisplay(String mDisplay) { this.mDisplay = mDisplay; return this; }
        public Computer build() { return new Computer(this); }
    }
}

Usage example:

public static void main(String[] args) {
    Computer macbook = new Computer.Builder()
        .setmBoard("board")
        .setmDisplay("sowhat")
        .setmOs("Mac")
        .build();
    System.out.println(macbook);
}

2. Privatize constructors of utility classes

Utility classes such as java.util.Arrays should not be instantiated; make their constructors private.

public class Arrays {
    private static final int MIN_ARRAY_SORT_GRAN = 8192;
    private static final int INSERTIONSORT_THRESHOLD = 7;
    private Arrays() { }
}

3. Avoid creating unnecessary objects

Prefer primitive types over boxed types, reuse static fields, employ connection pools, and keep large objects short‑lived to reduce GC pressure.

// Example showing the cost of boxing Long in a tight loop
public class Sum {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        Long sum = 0L; // boxed object
        for (long i = 0; i < Integer.MAX_VALUE; i++) {
            sum = sum + i; // creates billions of Long objects
        }
        System.out.println("spend time:" + (System.currentTimeMillis() - start) + "ms");
    }
}

Replacing the boxed Long with a primitive long reduces execution time dramatically.

4. Avoid using finalizers

Finalizers are unpredictable and may never run; rely on explicit resource management (try‑with‑resources) instead of finalize() or System.gc().

5. Minimize class and member visibility (Law of Demeter)

Keep fields private and expose only necessary behavior to reduce coupling.

6. Minimize mutability

Declare fields final whenever possible to simplify thread‑safety.

7. Prefer composition over inheritance

Use wrapper classes rather than extending across package boundaries to avoid fragile hierarchies.

8. Prefer interfaces to abstract classes

Java allows multiple interface implementations, supporting the Open/Closed principle; use skeletal abstract classes only when many implementations share common code.

9. Use var‑args cautiously

Var‑args create an array on each call; for performance‑critical code, provide overloaded methods for the most common argument counts.

10. Return empty collections instead of null

Returning Collections.EMPTY_LIST or an empty array avoids unnecessary null checks.

11. Prefer standard exceptions

Using familiar JDK exceptions improves readability and reduces class‑loading overhead.

12. Replace magic int constants with enums

Enums provide type safety and expressive code.

13. Minimize the scope of local variables

Declare variables close to their first use and keep methods small to aid GC and improve readability.

14. Use BigDecimal for precise decimal arithmetic

Floating‑point types introduce rounding errors; BigDecimal should be used for financial calculations.

15. Prefer StringBuilder / StringBuffer for mutable strings

String is immutable; for frequent modifications use the mutable builders.

16. Close resources separately

Closing resources in separate try blocks prevents one failure from masking another.

17. Efficient primitive‑to‑String conversion

Use Integer.toString() (fastest), then String.valueOf(), and avoid concatenation with + "" (slowest).

18. Null out references after use

Explicitly setting unused references to null helps the GC reclaim memory sooner.

19. Constant‑first comparisons

Write if (1 == i) to avoid accidental assignment errors.

20. Use "literal".equals(variable) to avoid NPE

Placing the literal first guarantees a non‑null call.

21. Prefer synchronized blocks over synchronized methods

Lock only the critical section to reduce contention.

22. Keep methods small

Small methods are more likely to be inlined by the JIT, improving performance.

23. Write meaningful comments

Even well‑written code benefits from clear class and method documentation.

References: Alibaba Java Coding Guidelines, Builder Pattern, finalize & GC, Deep Dive into String.

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 PatternsJavaperformanceMemory Managementconcurrencybest practices
Full-Stack Internet Architecture
Written by

Full-Stack Internet Architecture

Introducing full-stack Internet architecture technologies centered on Java

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.