45 Proven Tips to Write Clean, Maintainable Java Code
This article shares 45 practical techniques—from naming conventions and formatting rules to exception handling, thread safety, and design‑pattern usage—that help developers write clearer, more robust Java code, reduce technical debt, and improve overall software quality.
Hello everyone, I'm Su San.
Maintaining code left by a departed teammate can be painful: long methods, tangled if‑else chains, and unclear intent make it hard to understand and impossible to ask questions.
Much of this pain stems from poor coding standards; writing clean, well‑commented code can solve many of these issues. Below are 45 concise tips covering naming, formatting, comments, refactoring, and other best practices.
1. Naming Conventions
Names should be self‑explanatory.
Descriptive
Instead of int i = 0; use int count = 0; to convey meaning.
Readable
Replace unreadable names like private String sfzh; with meaningful English names such as private String idCardNo; and private String phone;.
2. Code Formatting
Good formatting improves readability. Follow these rules:
Appropriate spacing
Align braces
Limit line length
Modern IDEs provide one‑click formatting.
3. Writing Comments
Comments should fill the gaps when code cannot express intent clearly. Good comments:
Explain why code exists
Document parameters and return values
Provide warnings (e.g., non‑null constraints)
Use TODO for unfinished parts
4. Extract Try‑Catch Logic
Move the core logic inside a try‑catch block to a separate method to keep the main flow clean.
protected boolean internalCancel(String appName, String id, boolean isReplication) {
try {
read.lock();
doInternalCancel(appName, id, isReplication);
} finally {
read.unlock();
}
// remaining code
}
private boolean doInternalCancel(String appName, String id, boolean isReplication) {
// actual cancel logic
}5. Keep Methods Short
Long methods are hard to read; split them into smaller, focused methods.
6. Extract Duplicate Code
When the same code appears in multiple places, extract it into a utility class or a common superclass.
7. Use Early Returns
Replace deep nested if‑else chains with early return statements for clarity.
if (!condition1) { return; }
if (!condition2) { return; }
// ...
System.out.println("三友的java日记");8. Simplify Complex Conditions
Break complicated boolean expressions into well‑named variables.
boolean sanyouOrBlank = StringUtils.isBlank(person.getName()) || "三友的java日记".equals(person.getName());
boolean ageGreaterThanTen = person.getAge() != null && person.getAge() > 10;
boolean isHanNational = "汉".equals(person.getNational());
if (sanyouOrBlank && ageGreaterThanTen && isHanNational) {
// handle logic
}9. Elegant Parameter Validation
Use Bean Validation annotations like @NotBlank and @Valid instead of manual checks.
@Data
@ToString
public class AddPersonRequest {
@NotBlank(message = "人员姓名不能为空")
private String name;
@NotBlank(message = "身份证号不能为空")
private String idCardNo;
}
@PostMapping
public void addPerson(@RequestBody @Valid AddPersonRequest req) {
// business logic
}10. Unified Return Structure
Standardize API responses to a fixed JSON format.
{
"code": 0,
"message": "成功",
"data": "返回数据"
}11. Global Exception Handling
Leverage Spring’s @ControllerAdvice to avoid repetitive try‑catch blocks.
@GetMapping("/{id}")
public Result<T> selectPerson(@PathVariable("id") Long personId) {
try {
PersonVO vo = personService.selectById(personId);
return Result.success(vo);
} catch (Exception e) {
// log error
return Result.error("系统异常");
}
}12. Avoid Returning Null
Use @NonNull / @Nullable annotations or return Optional instead of null.
public Optional<Person> getPersonById(Long personId) {
return Optional.ofNullable(personService.selectById(personId));
}13. Logging Standards
Make logs searchable with clear keywords
Log stack traces for errors
Use appropriate log levels
Avoid logging huge payloads (e.g., Base64 images)
14. Consistent Libraries
Choose a single library for a given purpose (e.g., JSON parsing) to avoid conflicts.
15. Prefer Utility Classes
Use utility methods for common checks instead of manual code.
if (!CollectionUtils.isEmpty(persons)) {
// process
}16. Prefer Composition Over Inheritance
Inject dependencies rather than extending classes.
public class OrderService {
private UserService userService = new UserService(); // composition
} public class OrderService {
private UserService userService; // aggregation
public void setUserService(UserService us) { this.userService = us; }
}17. Use Design Patterns Wisely
Apply patterns like Strategy for extensible features (e.g., message notification).
public interface MessageNotifier {
boolean support(int type);
void notify(User user, String content);
}
@Component
public class SMSMessageNotifier implements MessageNotifier { /* ... */ }
public class AppMessageNotifier implements MessageNotifier { /* ... */ }
@Resource
private List<MessageNotifier> notifiers;
public void notifyMessage(User user, String content, int type) {
for (MessageNotifier n : notifiers) {
if (n.support(type)) { n.notify(user, content); }
}
}18. Avoid Overusing Design Patterns
Don’t force a pattern where simple code suffices.
19. Interface‑Based Programming
Program to abstractions to allow easy swapping of implementations (e.g., file storage).
public interface FileStorage {
String store(String fileName, byte[] bytes);
}
@Autowired
private FileStorage fileStorage;20. Regular Refactoring
Continuously improve legacy code as requirements evolve.
21. Null‑Check Discipline
Guard against NPEs by checking for null or using Optional.
22. Override toString in POJOs
Facilitates debugging and logging.
23. Replace Magic Numbers with Constants
private static final String GUANG_DONG_PROVINCE = "广东省";
public void sayHello(String province) {
if (GUANG_DONG_PROVINCE.equals(province)) {
System.out.println("靓仔~~");
} else {
System.out.println("帅哥~~");
}
}24. Release Resources in finally
Ensure locks or IO streams are always released.
25. Use Thread Pools
Reuse threads to reduce creation overhead and improve stability.
26. Name Threads
Helpful for log tracing.
27. Volatile for Visibility
Guarantee that changes to a flag are seen by other threads.
28. Reduce Lock Scope
Lock only the critical section to improve concurrency.
29. Define Enums for Types
Replace raw numbers with meaningful enum constants.
30. Set Timeouts on Remote Calls
Prevent threads from hanging indefinitely.
31. Pre‑size Collections
Specify initial capacity to avoid costly resizing.
32. Avoid BeanUtils for Copying
Prefer compile‑time mappers like MapStruct for better performance.
33. Use StringBuilder for Concatenation
StringBuilder sb = new StringBuilder();
String result = sb.append("123").append("456").append("789").toString();34. Specify Rollback Exceptions
Declare which exceptions should trigger transaction rollback.
35. Beware of Self‑Invocation with Proxies
Internal method calls bypass Spring AOP proxies, disabling transactional behavior.
36. Select Only Needed Columns
Reduce network load and enable index‑only scans.
Wrappers.query().select("name");37. Avoid DB Calls Inside Loops
Batch queries and map results instead of per‑iteration lookups.
List<Person> persons = personMapper.selectByIds(ids);
Map<Long, PersonExt> extMap = personExtMapper.selectByIds(ids)
.stream().collect(Collectors.toMap(PersonExt::getPersonId, Function.identity()));38. Prefer Business Logic Over Multi‑Table Joins
Join operations can be inefficient; fetch data in separate queries when possible.
39. Use Code Inspection Plugins
Tools like Alibaba’s code check plugin help enforce standards.
40. Communicate with Teammates
Seek guidance early to avoid pitfalls when entering new projects.
References: "Clean Code", "Alibaba Java Development Manual", and related articles.
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.
Su San Talks Tech
Su San, former staff at several leading tech companies, is a top creator on Juejin and a premium creator on CSDN, and runs the free coding practice site www.susan.net.cn.
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.
