- 浏览: 67228 次
- 性别:
- 来自: 北京
最近访客 更多访客>>
最新评论
-
sunwang810812:
这两个方法都对,只不过我个人觉得,泛型方法的主要目的是为了 p ...
java泛型方法的使用 -
a596620989:
第二个方法是不能通过编译的,会报T can't be reso ...
java泛型方法的使用 -
Javakeith:
...
java泛型 -
bannamoon:
两个方法当然有区别了。当你需要应用泛型规则的时候。第二个方法就 ...
java泛型方法的使用 -
luoping0425:
Learning English!
PEACE—宁静
出自《java puzzle》
下面的程序循环遍历了一个int类型的数组序列,并且记录了满足某个特定属性的数组个数。那么,该程序会打印出什么呢?
该程序用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.ArrayIndexOutOfBoundsException: 2
at Loop1.thirdElementIsThree(Loop1.java:19)
at Loop1.main(Loop1.java:13)
很明显,在thirdElementIsThree方法中有一个bug:它抛出了一个ArrayIndexOutOfBoundsException异常。这个异常先前伪装成了那个可怕的基于异常的循环的终止条件。
如果传递给thirdElementIsThree的参数具有3个或更多的元素,并且其第三个元素等于3,那么该方法将返回true。问题是在这些条件不满足时它会做些什么呢。如果你仔细观察其值将会被返回的那个布尔表达式,你就会发现它与大多数布尔AND操作有一点不一样。这个表达式是a.length >= 3 & a[2] == 3。通常,你在这种情况下看到的是 && 操作符,而这个表达式使用的是 & 操作符。那是一个位AND操作符吗?
事实证明 & 操作符有其他的含义。除了常见的被当作整型操作数的位AND操作符之外,当被用于布尔操作数时,它的功能被重载为逻辑AND操作符[JLS 15.22.2]。这个操作符与更经常被使用的条件AND操作符有所不同,& 操作符总是要计算它的两个操作数,而 && 操作符在其左边的操作数被计算为false时,就不再计算右边的操作数了[JLS 15.23]。因此,thirdElementIsThree方法总是要试图访问其数组参数的第三个元素,即使该数组参数的元素不足3个也是如此。订正这个方法只需将 & 操作符替换为 && 操作符即可。通过这样的修改,这个程序就可以打印出我们所期望的2了:
private static boolean thirdElementIsThree(int[] a) {
return a.length >= 3 && a[2] == 3;
}
正像有一个逻辑AND操作符伴随着更经常被使用的条件AND操作符一样,还有一个逻辑OR操作符(|)也伴随着条件OR操作符(||)[JLS 15.22.2,15.24]。| 操作符总是要计算它的两个操作数,而 || 操作符在其左边的操作数被计算为true时,就不再计算右边的操作数了。我们一不注意,就很容易使用了逻辑操作符而不是条件操作符。遗憾的是,编译器并不能帮助你发现这种错误。有意识地使用逻辑操作符的情形非常少见,少到了我们对所有这样使用的程序都应该持怀疑态度的地步。如果你真的想使用这样的操作符,为了是你的意图清楚起见,请加上注释。
总之,不要去用那些可怕的使用异常而不是使用显式的终止测试的循环惯用法,因为这种惯用法非常不清晰,而且会掩盖bug。要意识到逻辑AND和OR操作符的存在,并且不要因无意识的误用而受害。对语言设计者来说,这又是一个操作符重载会导致混乱的明证。对于在条件AND和OR操作符之外还要提供逻辑AND和OR操作符这一点,并没有很明显的理由。如果这些操作符确实要得到支持的话,它们应该与其相对应的条件操作符存在着视觉上的明显差异。
下面的程序循环遍历了一个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.ArrayIndexOutOfBoundsException: 2
at Loop1.thirdElementIsThree(Loop1.java:19)
at Loop1.main(Loop1.java:13)
很明显,在thirdElementIsThree方法中有一个bug:它抛出了一个ArrayIndexOutOfBoundsException异常。这个异常先前伪装成了那个可怕的基于异常的循环的终止条件。
如果传递给thirdElementIsThree的参数具有3个或更多的元素,并且其第三个元素等于3,那么该方法将返回true。问题是在这些条件不满足时它会做些什么呢。如果你仔细观察其值将会被返回的那个布尔表达式,你就会发现它与大多数布尔AND操作有一点不一样。这个表达式是a.length >= 3 & a[2] == 3。通常,你在这种情况下看到的是 && 操作符,而这个表达式使用的是 & 操作符。那是一个位AND操作符吗?
事实证明 & 操作符有其他的含义。除了常见的被当作整型操作数的位AND操作符之外,当被用于布尔操作数时,它的功能被重载为逻辑AND操作符[JLS 15.22.2]。这个操作符与更经常被使用的条件AND操作符有所不同,& 操作符总是要计算它的两个操作数,而 && 操作符在其左边的操作数被计算为false时,就不再计算右边的操作数了[JLS 15.23]。因此,thirdElementIsThree方法总是要试图访问其数组参数的第三个元素,即使该数组参数的元素不足3个也是如此。订正这个方法只需将 & 操作符替换为 && 操作符即可。通过这样的修改,这个程序就可以打印出我们所期望的2了:
private static boolean thirdElementIsThree(int[] a) {
return a.length >= 3 && a[2] == 3;
}
正像有一个逻辑AND操作符伴随着更经常被使用的条件AND操作符一样,还有一个逻辑OR操作符(|)也伴随着条件OR操作符(||)[JLS 15.22.2,15.24]。| 操作符总是要计算它的两个操作数,而 || 操作符在其左边的操作数被计算为true时,就不再计算右边的操作数了。我们一不注意,就很容易使用了逻辑操作符而不是条件操作符。遗憾的是,编译器并不能帮助你发现这种错误。有意识地使用逻辑操作符的情形非常少见,少到了我们对所有这样使用的程序都应该持怀疑态度的地步。如果你真的想使用这样的操作符,为了是你的意图清楚起见,请加上注释。
总之,不要去用那些可怕的使用异常而不是使用显式的终止测试的循环惯用法,因为这种惯用法非常不清晰,而且会掩盖bug。要意识到逻辑AND和OR操作符的存在,并且不要因无意识的误用而受害。对语言设计者来说,这又是一个操作符重载会导致混乱的明证。对于在条件AND和OR操作符之外还要提供逻辑AND和OR操作符这一点,并没有很明显的理由。如果这些操作符确实要得到支持的话,它们应该与其相对应的条件操作符存在着视觉上的明显差异。
发表评论
-
有毒的括号垃圾
2009-05-16 17:01 1069出自《java puzzle》 你能否举出这样一个合法的J ... -
诵读困难者的一神论
2009-05-08 15:17 1079出自《java puzzle》 从前有一个人,他认为世上只 ... -
烧焦到无法识别
2009-05-06 00:01 1013出自《java puzzle》 下面 ... -
反射的污染
2009-04-30 14:25 2451出自《java puzzle》 这个谜题举例说明了一个关于 ... -
不情愿的构造器
2009-04-13 23:38 1012出自《java puzzle》 尽管 ... -
不受欢迎的宾客
2009-04-10 13:16 826出自《java puzzle》 本谜题中的程序所建模的系统, ... -
极端不可思议
2009-04-09 13:38 853出自《java puzzle》 本 ... -
同一性的危机
2009-04-08 13:46 730出自《java puzzle》 下面的程序是不完整的,它缺 ... -
你的隐私正在被公开
2009-04-07 22:34 716出自《java puzzle》 私 ... -
终极危难
2009-04-03 11:48 749出自《java puzzle》 本谜题旨在检验当你试图隐藏一 ... -
进口税
2009-04-02 11:08 770出自《java puzzle》 在5.0 ... -
一揽子交易
2009-04-01 10:25 996出自《java puzzle》 下面这个程序设计在不同的包 ... -
灰色的阴影
2009-03-24 11:33 982出自《java puzzle》 下面 ... -
对字符串上瘾
2009-03-23 10:38 780出自 《java puzzle》 一个名字可以被用来引用位于 ... -
一件私事
2009-03-21 13:24 674出自 《java puzzle》 在下面的程序中,子类的一 ... -
一种疑似排序的惊人传奇
2009-03-19 10:43 679出自《java puzzle》 下 ... -
名字游戏
2009-03-18 15:35 907出自《java puzzle》 下面 ... -
一行的方法
2009-03-14 16:27 865出自《java puzzle》 现 ... -
差是几个
2009-03-12 13:21 722出自《java puzzle》 下面的程序在计算一个int数 ... -
产生它的散列码
2009-03-11 09:35 728出自 《java puzzle》 本 ...
相关推荐
mybatis启动无线循环的抛出异常类,只要用这个继承,就可以抛出异常
这段描述进一步明确了代码示例的具体语言环境为Java,并强调这是一个简单的示例,旨在帮助读者理解如何在Java中实现异常抛出。Java作为一种广泛应用的面向对象编程语言,提供了丰富的异常处理机制,包括`throw`...
谜题42:异常为循环而抛 谜题43:异常地危险 谜题44:切掉类 谜题45:令人疲惫不堪的测验 Java谜题5——类谜题 谜题46:令人混淆的构造器案例 谜题47:啊呀!我的猫变成狗了 谜题48:我所得到的都是静态的 ...
根据给定的信息,本文将详细解析“C#异常抛出和排序功能”这一主题,包括如何在C#中显式地引发异常以及实现数组的排序。 ### C#中的异常处理 #### 异常概述 异常是在程序运行时发生的错误或意外情况。C#提供了强大...
这种异常是在运行时抛出的,而不是在编译期。 例如,在遍历集合时,修改集合的内容可能会引发ConcurrentModificationException异常: for (Student stu : students) { if (stu.getId() == 2) students.remove...
在循环体内抛出异常会导致循环提前终止,并且可能影响循环外的数据状态。为了减少这种负面影响,应该尽量将异常处理逻辑放在循环外部。这样即使循环内部出现异常,也能够确保循环能够继续执行或安全地终止。 - **...
15. **类循环依赖错误**:`ClassCircularityError` - 初始化类时,检测到类之间的循环依赖,会抛出此异常。 16. **类格式错误**:`ClassFormatError` - 当读取的类文件格式不符合Java虚拟机规范时,会抛出此异常。 ...
15. **类循环依赖错误:ClassCircularityError** - 初始化类时,如果检测到类之间的循环依赖,会抛出此异常。 16. **类格式错误:ClassFormatError** - 当Java虚拟机尝试读取的类文件格式不正确时,会抛出此异常。 ...
在Java编程中,当一个线程抛出一个未捕获的异常时,系统会寻找该线程的`UncaughtExceptionHandler`。默认情况下,Android系统会终止应用并显示一个错误对话框。我们可以通过设置自定义的`UncaughtExceptionHandler`...
例如,如果一个对象实际上是`String`类型,而我们尝试将其转换为`Integer`类型,则会抛出此类异常。 #### 4. NegativeArraySizeException - 数组负大小异常 当创建数组时指定的大小为负数,Java会抛出`...
8. StackOverflowError:当调用栈超过其最大深度时抛出,通常是由于无限递归或其他无限制的循环引起的。 9. NoClassDefFoundError:在运行时无法找到类的定义时抛出,可能是由于类路径配置问题或依赖缺失。 了解...
当队列空时,可以抛出异常表示队列为空。 3. `isEmpty`: 检查队列是否为空。 4. `isFull`: 检查队列是否已满。 5. `peek`: 查看队首元素但不移除。 6. `size`: 返回队列中元素的数量。 在C++中,这些方法的实现可能...
12. **避免在循环中捕获异常**:这可能会隐藏循环内部的错误,使得问题不易发现。 13. **异常处理与资源管理**:在使用诸如文件、网络连接等资源时,通常会在finally块中关闭它们,以防止资源泄露。 14. **异常...
理解何时抛出异常(`throw`)、如何捕获异常(`catch`)以及在`finally`块中执行的代码是解决异常谜题的关键。此外,Java提供了多个预定义的异常类,如`NullPointerException`、`ArrayIndexOutOfBoundsException`,...
循环依赖是指两个或多个Bean之间形成一个闭环,彼此依赖对方,导致Spring容器在初始化Bean时无法确定创建顺序,从而抛出异常。 1. 循环依赖的定义: 循环依赖是指Bean A依赖于Bean B,同时Bean B又依赖于Bean A的...
第三个示例App9_3.java中,通过判断变量b是否为0来决定是否抛出ArithmeticException异常。如果b为0,则抛出异常,否则执行除法运算并打印结果。 在第四个示例App9_4.java中,演示了方法中的参数值异常。multi方法...
9. **字符串转换为数字异常:NumberFormatException** - 尝试将非数字字符串转换为数值类型时,会抛出此异常。 10. **操作数据库异常:SQLException** - 在处理数据库连接、查询或其他操作时,如果出现错误,会抛出...
- **异常概述**:当试图访问或修改类、字段或方法时,由于权限不足而抛出。 - **典型场景**: - 尝试访问私有或受保护的成员。 - 类型转换失败。 - **处理方法**: - 确保具有正确的访问权限。 - 使用适当的方法...
- **ClassCircularityError**:在初始化一个类时,若检测到类之间循环依赖则抛出。 - **ClassFormatError**:当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。 - **Error**...