易截截图软件、单文件、免安装、纯绿色、仅160KB

Java解惑4 42异常为循环所抛

下面的程序循环遍历了一个int类型的数组序列,并且记录了满足某个特定属性的数组个数。那么,该程序会打印出什么呢?
public class Loop {
public static void main(String[] args) {
int[][] tests = { { 6, 5, 4, 3, 2, 1 }, { 1, 2 },
{ 1, 2, 3 }, { 1, 2, 3, 4 }, { 1 } };
int successCount = 0;
try {
int i = 0;
while (true) {
if (thirdElementIsThree(tests[i++]))
successCount ++;
}
} catch(ArrayIndexOutOfBoundsException e) {
// No more tests to process
}
System.out.println(successCount);
}
private static boolean thirdElementIsThree(int[] a) {
return a.length >= 3 & a[2] == 3;
}
}
该程序用thirdElementIsThree方法测试了tests数组中的每一个元素。遍历这个数组的循环显然是非传统的循环:它不是在循环变量等于数组长度的时候终止,而是在它试图访问一个并不在数组中的元素时终止。尽管它是非传统的,但是这个循环应该可以工作。如果传递给thirdElementIsThree的参数具有3个或更多的元素,并且其第三个元素等于3,那么该方法将返回true。对于tests中的5个元素来说,有2个将返回true,因此看起来该程序应该打印2。如果你运行它,就会发现它打印的时0。肯定是哪里出了问题,你能确定吗?
事实上,这个程序犯了两个错误。第一个错误是该程序使用了一种可怕的循环惯用法,该惯用法依赖的是对数组的访问会抛出异常。这种惯用法不仅难以阅读,而且运行速度还非常地慢。不要使用异常来进行循环控制;应该只为异常条件而使用异常[EJ Item 39]。为了纠正这个错误,可以将整个try-finally语句块替换为循环遍历数组的标准惯用法:
for (int i = 0; i < test.length; i++)
if (thirdElementIsThree(tests[i]))
successCount++;
如果你使用的是5.0或者是更新的版本,那么你可以用for循环结构来代替:
for (int[] test : tests)
if(thirdElementIsThree(test))
successCount++;
就第一个错误的糟糕情况来说,只有它自己还不足以产生我们所观察到的行为。然而,订正该错误可以帮助我们找到真正的bug,它更加深奥:
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsExc


相关文档:

Java Native Method[还没来得及翻译]

The goal for this chapter is to introduce you to Java's native methods. If you are new to Java, you may not know what native methods are, and even if you are an experienced Java developer, you may not have had a reason to learn more about native methods. At the conclusion of this chapter you should ......

Java解惑3 29循环者的新娘

请提供一个对i的声明,将下面的循环转变为一个无限循环:
while (i != i) {
}
这个循环可能比前一个还要使人感到困惑。不管在它前面作何种声明,它看起来确实应该立即终止。一个数字总是等于它自己,对吗?
对,但是IEEE 754浮点算术保留了一个特殊的值用来表示一个不是数字的数量[IEEE 754]。这个值就是NaN(“ ......

Java解惑3 31循环者的鬼魂

请提供一个对i的声明,将下面的循环转变为一个无限循环:
while (i != 0) {
i >>>= 1;
}
回想一下,>>>=是对应于无符号右移操作符的赋值操作符。0被从左移入到由移位操作而空出来的位上,即使被移位的负数也是如此。
这个循环比前面三个循环要稍微复杂一点,因为其循环体非空。在其循环题中, ......

Java解惑3 34被奇数击倒了

与谜题26和27中的程序一样,下面的程序有一个单重的循环,它记录迭代的次数,并在循环终止时打印这个数。那么,这个程序会打印出什么呢?
public class Count {
public static void main(String[] args) {
final int START = 2000000000;
int count = 0;
for (float f = START; f < S ......

Java解惑4 39你好,再见!

下面的程序在寻常的Hello world程序中添加了一段不寻常的曲折操作。那么,它将会打印出什么呢?
public class HelloGoodbye {
public static void main(String[] args) {
try {
System.out.println("Hello world");
System.exit(0);
} finally {
System.o ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号