如下所示代码:
public class Example042 {
public static void main(String[] args) {
int[][] tests = { { 6, 5, 4, 3, 2, 1 }, { 1, 2 }, { 1, 2, 3 },
{ 1, 2, 3, 4 }, { 1 } };
System.out.println("func1 out : " + func1(tests));
}
private static int func1(int[][] tests) {
int successCount = 0;
try {
int i = 0;
while (true) {
if (thirdElementIsThree1(tests[i++])) {
successCount++;
}
}
} catch (ArrayIndexOutOfBoundsException e) {
// No more tests to process
}
return successCount;
}
private static boolean thirdElementIsThree1(int[] a) {
return a.length >= 3 & a[2] == 3;
}
}
输出结果:
func1 out : 0
结果分析:
上述代码有两个很严重的BUG。第一个BUG是使用了可能产生异常的条件做循环控制;第二个是错误使用“&”和“&&”。
使用可能产生异常的条件做循环控制不仅难以阅读,而且运行速度还非常地慢。不要使用异常来进行循环控制,应该只为异常条件而使用异常。可以使用如下代码来重写func1:
private static int func1(int[][] tests) {
int successCount = 0;
try {
for (int[] test : tests) {
if (thirdElementIsThree1(test)) {
successCount++;
}
}
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
return successCount;
}
修正后的代码输出结果依然存在问题,而且会捕获到数组越界的异常。问题出现在thirdElementIsThree1方法上。这个方法错误的使用了“&”,本来这里是需要使用“&&”的,如下:
private static boolean thirdElementIsThree1(int[] a) {
return a.length >= 3 && a[2] == 3;
}
为什么使用“&”会抛出异常呢?在func1中导致结果输出为0呢?& 操作符有其他的含义。除了常见的被当作整型操作数的位 AND 操作符之外,当被用于布尔操作数时,它的功能被重载为逻辑 AND 操作符。这个操作符与更经常被使用的条件 AND 操作符有所不同,& 操作符总是要计算它的两个操作数,而 && 操作符在其左边的操作数被计算为 false 时,就不再计算右边的操作数了。因此,thirdElementIsThree1 方法总是要试图访问其数组参数的第三个元素,即使该数组参数的元素不足 3 个也是如此。
同样的,还有一个逻辑 OR 操作符(| ) 也伴随着条件 OR 操作符(|| ), | 操作符总是要计算它的两个操作数,而 || 操作符在其左边的操作数被计算为true 时,就不再计算右边的操作数了。
注:本【java解惑】系列均是博主阅读《java解惑》原书后将原书上的讲解和例子部分改编然后写成博文进行发布的。所有例子均亲自测试通过并共享在github上。通过这些例子激励自己惠及他人。同时本系列所有博文会同步发布在博主个人微信公众号搜索“爱题猿”或者“ape_it”方便大家阅读。如果文中有任何侵犯原作者权利的内容请及时告知博主以便及时删除如果读者对文中的内容有异议或者问题欢迎通过博客留言或者微信公众号留言等方式共同探讨。
源代码地址https://github.com/rocwinger/java-disabuse
本文出自 “winger” 博客,谢绝转载!