Code Review em Java: o que procurar no código alheio

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que code review não é sobre criticar, mas sobre qualidade

\n

Imagine: você abre um pull request de um colega. São 500 linhas de código, cheira a copia-cola, e em um lugar alguém esqueceu de fechar um recurso. Sua tarefa não é apenas encontrar bugs, mas melhorar o código. Code review em Java não é uma supervisão policial, mas uma criação colaborativa. Um bom revisor salva a equipe da dívida técnica; um ruim desmotiva ou deixa passar vulnerabilidades.

\n

Neste artigo, explicarei o que verificar em code review em Java para não perder tempo com detalhes, mas não perder o crítico. Você receberá um checklist pronto e exemplos da prática.

\n\n

Arquitetura e design: olhando para a raiz

\n

Antes de mergulhar nos detalhes, avalie o panorama geral. Uma arquitetura ruim não se cura com formatação.

\n

Violação do SOLID

\n

Verifique se a classe não se tornou um "objeto divino". Exemplo de violação do Single Responsibility:

\n
public class OrderService {\n    public void createOrder(Order order) {\n        // validação\n        // cálculo de desconto\n        // envio de email\n        // registro de log\n        // salvamento no BD\n    }\n}\n
\n

Aqui há cinco motivos para mudança. O correto é extrair o registro de log e o envio para serviços separados.

\n

Complexidade excessiva

\n

Às vezes o código resolve um problema simples de forma complexa. Pergunte a si mesmo: "Pode ser mais simples?" Se sim, escreva na revisão. Lembre-se do princípio KISS.

\n\n

Segurança: brechas que não podem ser ignoradas

\n

Revisão de código Java deve incluir verificação de segurança. Mesmo que o projeto seja interno.

\n

Injeção de SQL

\n

Concatenação de strings é um mal:

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

O correto é usar PreparedStatement:

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

Vazamento de dados sensíveis

\n

Verifique se senhas, tokens ou números de cartão não estão sendo registrados em log. Use @ToString.Exclude no Lombok ou uma exclusão explícita.

\n

Comparação insegura de objetos

\n
// RUIM (comparação de referências)\nif (password == storedPassword) { ... }\n// BOM\nif (password.equals(storedPassword)) { ... }\n
\n\n

Desempenho: gargalos

\n

Não otimize prematuramente, mas também não ignore lentidões óbvias.

\n

Operações desnecessárias em loops

\n
// RUIM: length() é chamado toda vez\nfor (int i = 0; i < list.size(); i++) { ... }\n// BOM\nint size = list.size();\nfor (int i = 0; i < size; i++) { ... }\n
\n

Uso de Stream para tarefas simples

\n

Às vezes um loop comum é mais legível e rápido:

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

Vazamento de memória

\n

Verifique se não esqueceram de fechar InputStream, Connection ou Session. Use try-with-resources:

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

Legibilidade e estilo: código como um livro

\n

Code review checklist inclui obrigatoriamente a legibilidade. O código é escrito uma vez, lido dezenas de vezes.

\n

Números e strings mágicos

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

Métodos longos de

Blogs

Book Recommendations