18 Essential Code Review Rules Every Developer Should Follow

This article presents 18 practical code review guidelines covering comments, logging, naming, parameter validation, exception handling, modularity, concurrency, testing, formatting, compatibility, security, transaction, idempotency, middleware, code smells, and remote calls, offering concrete examples and best‑practice recommendations for Java developers.

macrozheng
macrozheng
macrozheng
18 Essential Code Review Rules Every Developer Should Follow

1. Add Necessary Comments

Good method and variable names serve as the best comments, but additional annotations are still valuable. Recommended comment rules include:

All classes must include creator, creation date, and a brief description.

Complex business logic or algorithms inside methods should have clear comments.

Generally describe the purpose of classes, methods, and variables.

Any warnings or TODO items must be clearly commented.

Use // for single‑line comments and /* */ for multi‑line comments.

If a piece of code is not understandable at first glance, add explanatory comments.

/**
 * @author 田螺
 * @date 2023/04/22 5:20 PM
 * @desc 田螺的实现类,捡田螺、卖田螺
 */
public class TianLuoClass {
    /**
     * This method adds two integer prices of TianLuo and returns the sum.
     * @param x first integer
     * @param y second integer
     * @return sum of the two integers
     */
    public int sellTianLuo(int x, int y) {
        return x + y;
    }
}

2. Logging Standards

Effective logging is crucial for troubleshooting. Ensure logs follow these rules:

Choose appropriate log levels: error, warn, info, debug. Avoid using info for error conditions.

Log method entry parameters and response results, especially for cross‑system calls.

Include key business parameters (e.g., userId, bizSeq) in business logs.

Sensitive data such as phone numbers or IDs must be masked.

Log unexpected situations, unknown exceptions, or business‑logic anomalies.

3. Naming Conventions

Java naming should be clear, concise, and understandable. Follow these guidelines:

Classes and interfaces use PascalCase.

Methods and variables use camelCase.

Constants use ALL_UPPER_CASE with underscores.

Prefer meaningful, self‑descriptive names.

4. Parameter Validation

Validate all input parameters (e.g., userId non‑null, amount ranges, userName length). Adopt a "check first, process later" approach.

5. Null‑Check Handling

Always check for null before accessing object properties to avoid NullPointerException.

if (object != null) {
    String name = object.getName();
}

if (CollectionUtils.isNotEmpty(tianLuolist)) {
    for (TianLuo temp : tianLuolist) {
        // do something
    }
}

6. Exception Handling Standards

Catch specific exceptions instead of generic Exception.

Log exception details for debugging.

Avoid treating unknown exceptions as simple failures.

Release resources in finally blocks or use try‑with‑resources.

Do not use e.printStackTrace(); use proper logging.

When catching an exception, log the full exception object.

Ensure caught exceptions match or are subclasses of thrown exceptions.

Never ignore caught exceptions; always log them.

Provide meaningful error codes for APIs.

Wrap business‑specific exceptions instead of throwing raw RuntimeException or Exception.

7. Modularity and Extensibility

Design code to be modular; interfaces should be extensible to accommodate future features without duplication.

8. Concurrency Control

Use thread‑safe collections like ConcurrentHashMap instead of HashMap.

Apply optimistic locking (version field) or pessimistic locking ( SELECT … FOR UPDATE) for database concurrency.

For single‑instance multi‑threading, use Java locks such as synchronized or ReentrantLock.

For clustered environments, use distributed locks like Redis or Zookeeper.

9. Unit Test Standards

Test class names end with Test (e.g., CalculatorTest).

Test method names start with test (e.g., testAdd).

Maintain at least 75% line coverage.

Include main‑flow, boundary, and exception cases, covering concurrency, idempotency, and middleware failures.

10. Code Formatting

Indent with four spaces.

Use braces to delimit code blocks.

Limit each line to 80 characters.

Order class members as: class variables, instance variables, constructors, public methods, private methods.

11. Interface Compatibility

When modifying public interfaces, ensure backward compatibility (e.g., add new parameters with default values or overload methods).

// Old interface
void oldService(A, B) {
    // call new service with null for new param
    newService(A, B, null);
}

// New interface
void newService(A, B, C) {
    // implementation
}

12. Clear Program Logic

Separate concerns by extracting validation, existence checks, and business actions into small, focused methods.

13. Security Guidelines

Validate all external inputs (type, size, format).

Use parameterized queries to prevent SQL injection.

Escape HTML/JS/CSS to avoid XSS.

Encrypt sensitive data in transit and at rest; avoid leaking secrets in logs.

Implement CSRF tokens for sensitive operations.

Adopt strong protocols (HTTPS/TLS) and perform regular security audits.

14. Transaction Control

Prefer programmatic transactions over declarative @Transactional when necessary.

Keep transaction scope limited to database operations.

Avoid remote calls inside transactions.

Do not process large data sets within a single transaction.

15. Idempotency Handling

Ensure repeated requests produce the same effect, typically by using unique identifiers, database constraints, or token mechanisms.

Insert with primary‑key/unique‑key conflict handling.

Status‑machine based idempotency.

Dedicated anti‑duplicate tables.

Token or distributed lock approaches.

16. Middleware Considerations (Database, Redis)

When using middleware, pay attention to connection pool settings, timeout configurations, query limits, result null‑checks, monitoring, schema compatibility, index usage, and potential performance pitfalls.

For databases: proper connection pool, pagination, limit clauses, slow‑query monitoring, and index design.

For Redis: consistent key naming, exception handling, connection pool tuning, avoid risky commands like hgetall, and guard against cache penetration, snowball, and stampede.

17. Code Smell Awareness

Reduce duplicate code by extracting common methods.

Encapsulate many parameters into DTOs.

Split long methods into smaller functions.

Simplify complex conditional logic.

Remove unused code and imports.

Avoid over‑engineering.

18. Remote Call Best Practices

Do not treat timeouts as outright failures; verify success before handling.

Catch and handle remote call exceptions gracefully.

Secure communication with encryption, authentication, and HTTPS/SSL.

Maintain service quality by limiting remote calls, optimizing payloads, and load balancing.

Ensure version compatibility between client and server.

Avoid loops of remote calls; prefer batch APIs.

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.

javasoftware-engineeringCode review
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.