Java 代码审查:检查什么以及如何提供反馈
\n代码审查不仅仅是形式上的流程,而是提高代码质量和团队专业水平的最有效方法之一。对于初级 Java 开发者来说,参与审查可能看起来令人生畏:“万一我漏掉了 bug 怎么办?”,“如何告诉同事他的代码不完美?”。在本文中,我们将分析在检查 Java 代码时应注意什么,以及如何提供有用且不伤人的反馈。
\n\n1. 检查 Java 代码中的什么:从语法到架构
\n代码审查不仅仅是查找拼写错误。优秀的审查者会系统地审视代码。以下是 Java 项目检查的主要类别:
\n\n1.1. 正确性与逻辑
\n第一个也是最重要的问题:“代码是否解决了既定任务?”。检查:
\n- \n
- 边界情况(null、空集合、负值)。 \n
- 条件语句和循环的逻辑。 \n
- 异常处理的正确性(不要使用
Exception作为通用解决方案)。 \n
糟糕代码示例:
\npublic int divide(int a, int b) {\n return a / b; // 潜在的除零错误\n}\n建议:
\npublic int divide(int a, int b) {\n if (b == 0) {\n throw new IllegalArgumentException("除数不能为零");\n }\n return a / b;\n}\n\n1.2. 可读性与风格
\nJava 是一种具有既定约定的语言(Java Code Conventions、Google Java Style)。注意:
\n- \n
- 变量、方法、类的命名(应具有意义)。 \n
- 格式化(缩进、空格、行长度)。 \n
- 是否存在魔法数字(将其提取为常量)。 \n
示例:
\n// 不好\ndouble x = 3.14159 * r * r;\n\n// 好\nprivate static final double PI = 3.14159;\ndouble area = PI * radius * radius;\n\n1.3. 性能与优化
\n对于 Java 尤其重要:
\n- \n
- 避免在循环中不必要地创建对象。 \n
- 在循环中使用
StringBuilder进行字符串拼接。 \n - 检查算法的复杂度(O(n)、O(n log n))。 \n
示例:
\n// 不好(创建了大量 String 对象)\nString result = "";\nfor (int i = 0; i < 1000; i++) {\n result += i;\n}\n\n// 好\nStringBuilder sb = new StringBuilder();\nfor (int i = 0; i < 1000; i++) {\n sb.append(i);\n}\nString result = sb.toString();\n\n1.4. 可测试性与测试
\n检查新代码是否被单元测试覆盖。注意:
\n- \n
- 是否存在针对边界情况的测试。 \n
- 单元测试中是否没有对外部系统(数据库、API)的依赖。 \n
- 测试本身的可读性(带有清晰消息的
assert方法)。 \n
2. 如何提供反馈:建设性且无毒性
\n即使是最正确的代码审查,如果反馈带有攻击性或不够具体,也可能失败。以下是给初学者的一些规则:
\n\n2.1. “三明治”法则
\n从积极方面开始,然后指出缺点,最后以鼓励结束。例如:
\n- \n
- 积极:“将验证提取到单独的方法中,这个主意很棒!” \n
- 意见:“但这里最好使用
Optional而不是返回 null,以避免NullPointerException”。 \n - 总结:“其余代码很干净,感谢你的工作!” \n
2.2. 使用“我”字句和提问
\n与其说“你写错了”,不如说:“我觉得当列表为空时,这里可能会出现 bug。你怎么看?”。这可以降低防御性反应,并将对话引向建设性的方向。