Code Review in Java: What to Look for in Someone Else's Code

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why Code Review is Not About Nitpicking, But About Quality

\n

Imagine: you open a colleague's pull request. There are 500 lines of code, it smells of copy-paste, and in one place someone forgot to close a resource. Your task is not just to find bugs, but to make the code better. Code review in Java is not police surveillance, but collaborative creativity. A good reviewer saves the team from technical debt, a bad one demotivates or lets vulnerabilities slip through.

\n

In this article, I will tell you what to check in a code review in Java, so you don't waste time on trivialities but don't miss the critical. You will get a ready-made checklist and real-world examples.

\n\n

Architecture and Design: Look at the Root

\n

Before diving into details, assess the big picture. Bad architecture cannot be fixed with formatting.

\n

Violation of SOLID

\n

Check if the class has turned into a "god object". An example of violating Single Responsibility:

\n
public class OrderService {\n    public void createOrder(Order order) {\n        // validation\n        // discount calculation\n        // sending email\n        // logging\n        // saving to DB\n    }\n}\n
\n

Here there are five reasons for change. The correct approach is to extract logging and sending into separate services.

\n

Excessive Complexity

\n

Sometimes code solves a simple problem in a complex way. Ask yourself: "Can it be simpler?" If yes, write it in the review. Remember the KISS principle.

\n\n

Security: Holes You Must Not Miss

\n

Java code review must include a security check. Even if the project is internal.

\n

SQL Injection

\n

String concatenation is evil:

\n
// BAD\nString query = "SELECT * FROM users WHERE name = '" + userName + "'";\nStatement stmt = connection.createStatement();\nResultSet rs = stmt.executeQuery(query);\n
\n

The correct way is to use PreparedStatement:

\n
// GOOD\nString query = "SELECT * FROM users WHERE name = ?";\nPreparedStatement pstmt = connection.prepareStatement(query);\npstmt.setString(1, userName);\nResultSet rs = pstmt.executeQuery();\n
\n

Leakage of Sensitive Data

\n

Check that passwords, tokens, or card numbers are not being logged. Use @ToString.Exclude in Lombok or explicit exclusion.

\n

Unsafe Object Comparison

\n
// BAD (reference comparison)\nif (password == storedPassword) { ... }\n// GOOD\nif (password.equals(storedPassword)) { ... }\n
\n\n

Performance: Bottlenecks

\n

Don't optimize prematurely, but don't miss obvious slowdowns either.

\n

Unnecessary Operations in Loops

\n
// BAD: length() is called every time\nfor (int i = 0; i < list.size(); i++) { ... }\n// GOOD\nint size = list.size();\nfor (int i = 0; i < size; i++) { ... }\n
\n

Using Stream for Simple Tasks

\n

Sometimes a regular loop is more readable and faster:

\n
// Overkill\nlist.stream().filter(x -> x > 5).collect(Collectors.toList());\n// Simple\nList<Integer> result = new ArrayList<>();\nfor (int x : list) {\n    if (x > 5) result.add(x);\n}\n
\n

Memory Leaks

\n

Check if InputStream, Connection, or Session were not forgotten to be closed. Use try-with-resources:

\n
try (Connection conn = getConnection();\n     PreparedStatement stmt = conn.prepareStatement(sql)) {\n    // work\n} catch (SQLException e) {\n    log.error("DB error", e);\n}\n
\n\n

Readability and Style: Code as a Book

\n

Code review checklist must include readability. Code is written once, read dozens of times.

\n

Magic Numbers and Strings

\n
// BAD\nif (status == 3) { ... }\n// GOOD\nprivate static final int STATUS_COMPLETED = 3;\nif (status == STATUS_COMPLETED) { ... }\n
\n

Long Me

Blogs

Book Recommendations