15 Golden Rules for High‑Performance, Maintainable Java Code

This article presents fifteen concrete Java performance‑optimization rules—from readable code and proper data structures to efficient string handling, database access, caching, multithreading, reflection, JVM tuning, and memory management—each illustrated with before/after code examples and practical advice.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
15 Golden Rules for High‑Performance, Maintainable Java Code

1. Introduction

Performance tuning is essential for improving application efficiency and user experience, but it should follow systematic, evidence‑based guidelines. The article outlines fifteen Java performance‑optimization golden rules covering readability, data‑structure choice, object creation, string handling, database calls, caching, multithreading, profiling, reflection, JVM features, avoiding reinventing the wheel, testability, synchronization, logging, and memory management.

2. Optimization Rules

Rule 1 – Start with Readability

Bad example:

int a = 0;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] % 2 == 0) {
        a += arr[i];
    }
}
System.out.println(a);

Good example (using streams):

int ret = Arrays.stream(arr)
    .filter(num -> num % 2 == 0)
    .sum();
System.out.println(ret);

The stream version is clearer and runs faster.

Rule 2 – Choose the Right Data Structure

Bad example (O(n) list lookup):

List<String> names = new ArrayList<>();
if (names.contains("pack")) {
    // ...
}

Good example (O(1) set lookup):

Set<String> names = new HashSet<>();
if (names.contains("pack")) {
    // ...
}

Rule 3 – Avoid Unnecessary Object Creation

Bad example (re‑compiling regex each call):

public static class Validator {
    public boolean isValidEmail(String email) {
        return email != null && Pattern.compile("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")
            .matcher(email).matches();
    }
}

Good example (compile once, reuse):

public static class Validator {
    private static final Pattern EMAIL_PATTERN = Pattern.compile(
        "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$");
    public boolean isValidEmail(String email) {
        return email != null && EMAIL_PATTERN.matcher(email).matches();
    }
}

Rule 4 – Efficient String Handling

Bad example (concatenation in a loop):

String result = "";
for (int i = 0; i < 1000; i++) {
    result += i; // creates a new String each iteration
}

Good example (StringBuilder):

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String result = sb.toString();

Or using streams:

String result = IntStream.range(0, 1000)
    .mapToObj(String::valueOf)
    .collect(Collectors.joining());

Rule 5 – Minimize Database Calls

Bad example (N separate queries):

for (int id : userIds) {
    User user = userRepository.findById(id);
}

Good example (single batch query):

List<User> users = userRepository.findAllById(userIds);

This obtains one connection and sends one SQL batch.

Rule 6 – Use Caching Wisely

Simple manual cache:

private final UserRepository userRepository;
Map<Integer, User> cache = new HashMap<>();
public User getUser(int id) {
    return cache.computeIfAbsent(id, userRepository::findById);
}

Annotation‑based cache (Spring):

@Service
public class UserService {
    private final UserRepository userRepository;
    @Cacheable("users")
    public User getUser(int id) { return userRepository.findById(id); }
    @CachePut(value = "users", key = "#user.id")
    public User updateUser(User user) { return userRepository.save(user); }
    @CacheEvict(value = "users", key = "#id")
    public void deleteUser(int id) { userRepository.deleteById(id); }
}

Rule 7 – Write Multithreaded Code Carefully

Bad example (sequential processing):

for (String file : files) {
    processFile(file);
}

Good example (parallel stream):

files.parallelStream().forEach(this::processFile);

Or using a thread pool:

ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 100, 60, TimeUnit.SECONDS,
    new ArrayBlockingQueue<>(100));
for (String file : files) {
    executor.submit(() -> processFile(file));
}
executor.shutdown();

Rule 8 – Analyze Before Optimizing

Use profiling tools such as JVisualVM, JProfiler, YourKit, or Java Flight Recorder to identify hot methods and memory hotspots.

Rule 9 – Optimize Reflection Calls

Typical reflective call:

Method method = getBridgedMethod();
return method.invoke(getBean(), args);

Optimized alternatives:

// MethodHandle
MethodHandles.Lookup lookup = MethodHandles.lookup();
MethodHandle mh = lookup.unreflect(getBridgedMethod());
mh.bindTo(getBean()).invokeWithArguments(args);

// CGLIB FastClass
FastClass fastClass = FastClass.create(getBean().getClass());
int index = fastClass.getIndex(new Signature(method.getName(),
    Type.getReturnType(method), Type.getArgumentTypes(method)));
fastClass.invoke(index, getBean(), args);

// ByteBuddy (omitted for brevity)

Only use reflection when flexibility is required (frameworks, annotations, dynamic loading).

Rule 10 – Leverage JVM Features

Key JVM optimizations include JIT compilation, GC tuning, escape analysis, and HotSpot internal mechanisms. Developers should focus on reducing large object allocations that trigger frequent GC.

Rule 11 – Don’t Reinvent the Wheel

Bad example (manual bubble sort):

for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr.length - 1; j++) {
        if (arr[j] > arr[j+1]) {
            int tmp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = tmp;
        }
    }
}

Good example (built‑in sort):

Arrays.sort(arr);
// or
Arrays.parallelSort(arr);

Rule 12 – Write Testable, Maintainable Code

Bad example (large monolithic method):

public void processOrder(Order order) { /* 200+ lines */ }

Good example (single‑purpose steps):

public void processOrder(Order order) {
    validate(order);
    applyDiscount(order);
    chargePayment(order);
    notifyUser(order);
}

Rule 13 – Minimize Synchronization Overhead

Bad example (synchronized method):

public synchronized void increment() {
    counter++;
}

Good example (AtomicInteger):

AtomicInteger counter = new AtomicInteger();
public void increment() {
    counter.incrementAndGet();
}

Rule 14 – Log Smartly

Bad example (unconditional System.out):

System.out.println("User logged in: " + user.getName());

Good example (conditional logger):

if (logger.isDebugEnabled()) {
    logger.debug("User logged in: {}", user::getName);
}

In production, use asynchronous logging frameworks such as Logback AsyncAppender or Log4j2 Async.

Rule 15 – Manage Memory Properly

Bad example (resources not closed):

public void queryData() {
    Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT * FROM users");
    // ... no close, leads to leak
}

Good example (try‑with‑resources):

public void queryData() {
    try (Connection conn = dataSource.getConnection();
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT * FROM users")) {
        // process results
    }
}

Cache leak example (static map) vs. Caffeine cache with expiration:

// Bad static map
public class Cache {
    private static final Map<Integer, User> USER_CACHE = new HashMap<>();
    public static void addUser(User user) { USER_CACHE.put(user.getId(), user); }
}

// Good Caffeine cache
public class AdvancedCache {
    private static final Cache<Integer, User> CACHE = Caffeine.newBuilder()
        .expireAfterWrite(10, TimeUnit.MINUTES)
        .maximumSize(1000)
        .build();
    public static void addUser(User user) { CACHE.put(user.getId(), user); }
    public static User getUser(int id) { return CACHE.getIfPresent(id); }
}

These practices help avoid memory leaks and keep applications performant.

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.

JavajvmperformanceoptimizationMemory Managementconcurrencycachingbest practices
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

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.