示例 11:资源泄露
修改前(错误) - 在Java中忘记关闭资源:
InputStream inputStream = null;
try {
inputStream = new FileInputStream("");
// 读取文件操作...
} catch (IOException e) {
();
}
// 忘记了关闭inputStream
资源泄露发生了因为inputStream
没有被关闭。
修改后(正确) - 使用try-with-resources确保资源关闭:
try (InputStream inputStream = new FileInputStream("")) {
// 读取文件操作...
} catch (IOException e) {
();
}
// 不需要手动关闭inputStream,try-with-resources会处理
示例 12:未考虑浮点数精度问题
修改前(错误) - 直接比较浮点数:
function areFloatsEqual(a, b) {
return a == b; // 浮点数比较可能不准确
}
浮点数直接比较可能因为精度问题导致比较结果不准确。
修改后(正确) - 使用阈值比较浮点数:
function areFloatsEqual(a, b, epsilon = 0.000001) {
return (a - b) < epsilon;
}
引入一个很小的数epsilon
来比较两个浮点数是否接近相等。
示例 13:在计算中未考虑数值溢出或下溢
修改前(错误) - 整数溢出:
public int add(int a, int b) {
return a + b; // 如果a和b都很大,可能会发生溢出
}
如果a
和b
都接近Integer.MAX_VALUE
,结果可能会溢出。
修改后(正确) - 检查溢出:
public int add(int a, int b) {
if (a > Integer.MAX_VALUE - b) {
throw new ArithmeticException("Integer overflow");
}
return a + b;
}
在执行加法之前检查溢出的可能性。
示例 14:函数或方法的输出依赖于未明确说明的外部状态
修改前(错误) - 使用全局变量:
let userRole;
function init() {
userRole = getCurrentUserRole(); // 设置全局变量
}
function canAccessResource() {
return userRole === 'admin'; // 使用全局变量
}
canAccessResource
的结果依赖于全局变量userRole
,这增加了代码的耦合性。
修改后(正确) - 明确传递参数:
function canAccessResource(userRole) {
return userRole === 'admin'; // 直接使用参数
}
const userRole = getCurrentUserRole();
canAccessResource(userRole); // 调用时传递参数
通过参数明确传递所需的状态,减少了对全局变量的依赖。
示例 15:全局状态被错误地修改,影响了系统的其他部分
修改前(错误) - 修改全局数组:
let globalArray = [1, 2, 3];
function addToArray(item) {
(item); // 直接修改全局数组
}
这段代码直接修改了全局数组,可能导致其他依赖这个数组的函数出现问题。
修改后(正确) - 不直接修改全局状态:
let globalArray = [1, 2, 3];
function addToArray(item) {
return (item); // 返回一个新数组,不修改原数组
}
globalArray = addToArray(4); // 更新全局数组
通过返回新数组而不是直接修改原数组,避免了全局状态的不可预知的改变。