31 Proven Java Code Optimizations to Boost Performance
This article presents a comprehensive collection of Java code optimization techniques—from using final modifiers and reusing objects to pre‑sizing collections and avoiding reflection—aimed at reducing code size, improving execution efficiency, and preventing common performance pitfalls in backend development.
Introduction
Code optimization is crucial for reducing code size and improving runtime efficiency, especially when there is time for thorough development and maintenance.
Optimization Goals
Reduce code size
Increase execution efficiency
Optimization Details
1. Use final for classes and methods
Marking classes and methods as final prevents inheritance and allows the JVM to inline methods, potentially improving performance by up to 50%.
2. Reuse objects
Prefer StringBuilder / StringBuffer over string concatenation to avoid creating unnecessary objects and reduce garbage‑collection overhead.
3. Prefer local variables
Parameters and temporary variables are stored on the stack, which is faster than heap allocation for static or instance variables.
4. Close streams promptly
Always close database connections and I/O streams after use to release resources and avoid heavy system overhead.
5. Avoid repeated calculations in loops
Cache results such as list.size() before the loop to reduce method‑call overhead.
for (int i = 0, length = list.size(); i < length; i++) { ... }6. Use lazy initialization
Instantiate objects only when needed, moving creation inside conditional blocks.
7. Use exceptions sparingly
Throwing exceptions incurs object creation and stack‑trace generation; use them only for error handling.
8. Place try‑catch outside loops
Wrap large code blocks with try‑catch rather than inside loops to avoid repeated exception‑handling overhead.
9. Pre‑size collections
Specify initial capacity for ArrayList, StringBuilder, HashMap, etc., to reduce resizing and copying costs.
10. Use System.arraycopy for bulk copies
Leverage native array copying for better performance.
11. Replace multiplication/division with bit shifts
Bit‑shift operations are faster for powers of two.
12. Avoid creating objects inside loops
Reuse a single object reference instead of allocating a new object each iteration.
13. Prefer arrays over ArrayList when size is known
Arrays provide faster indexed access without the overhead of dynamic resizing.
14. Prefer non‑synchronized collections unless thread safety is required
Use HashMap, ArrayList, StringBuilder instead of Hashtable, Vector, StringBuffer to avoid synchronization costs.
15. Do not declare public static final arrays
Public static final arrays can still be modified and expose internal state.
16. Use singleton pattern appropriately
Singletons reduce loading overhead when a single shared instance is sufficient.
17. Minimize static variables
Static references prevent garbage collection and can cause memory leaks.
18. Invalidate unused sessions
Call HttpSession.invalidate() to free session resources and avoid memory pressure.
19. Iterate RandomAccess collections with indexed for loops
For lists implementing RandomAccess, a classic for loop is faster than a foreach loop.
20. Prefer synchronized blocks over synchronized methods
Synchronize only the critical sections to reduce contention.
21. Declare constants as static final with uppercase names
This allows compile‑time inlining and clear distinction from variables.
22. Remove unused objects and imports
Eliminate dead code and unnecessary imports to keep the codebase clean.
23. Avoid reflection in performance‑critical paths
Reflection adds overhead; cache reflective objects if they must be used.
24. Use connection pools and thread pools
Reuse database connections and threads to avoid costly creation and destruction.
25. Use buffered I/O streams
BufferedReader/ BufferedWriter improve I/O throughput.
26. Choose appropriate List implementation
Use ArrayList for random access, LinkedList for frequent insertions/removals.
27. Limit the number of method parameters
Too many parameters reduce readability and increase error risk; encapsulate them in objects.
28. Put constant strings on the left side of equals()
Writing "constant".equals(variable) prevents NullPointerException.
29. Prefer i == value over value == i for readability
Both are equivalent, but the former aligns with typical coding style.
30. Do not use toString() on arrays
Array toString() yields an unreadable hash code; use Arrays.toString() instead.
31. Prefer toString() over String.valueOf() and concatenation for primitive conversion
toString()is the fastest method for converting primitives to strings.
32. Remove unused elements from shared collections
Failing to clean up shared collections can cause memory leaks.
33. Convert primitives to strings using toString()
toString()is faster than String.valueOf() and concatenation.
34. Iterate maps using entrySet iterator
Iterating over entrySet provides the most efficient access to keys and values.
35. Close resources in separate try‑catch blocks
Ensures each resource is closed even if another close operation throws an exception.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
