Java——异常谜题
1、谜题36 try和finally语句,代码如下,判断输出
public class Indecisive {
public static void main(String[] args) {
System.out.println(decision());
}
static boolean decision() {
try {
return true;
} finally {
return false;
}
}
}
最后的输出为false,为什么呢?这是因为try的异常结束(例如return,break,continue,throws)是不会影响finally语句块的执行。
2、谜题37 考察try catch的规则掌握程度
public class Arcane1 {
public static void main(String[] args) {
try {
System.out.println("Hello world");
} catch(IOException e) {
System.out.println("I've never seen
println fail!");
}
}
}
这段代码看着会编译通过,但是实际上编译都不能通过。这里就考察到被检查异常的一个基本原则。try里的代码println执行IO,但是它不能抛出IOException异常,而catch里检查的异常就是IOException,所以会出现编译不通过。语言规范中描述道:如果一个catch子句要捕获一个类型为E的被检查异常,而其相对应的try子句不能抛出E的某种子类型的异常,那么这就是一个编译期错误[JLS 11.2.3]。
public class Arcane2 {
public static void main(String[] args) {
try {
// If you have nothing nice to say, say nothing
} catch(Exception e) {
System.out.println("This can't
happen");
}
}
}
这段代码,如果你看了上面的,你肯定会以为编译不通过,可是他的编译 是通过的。为什么呢?因为Catch里捕捉的是Exception,捕获这个异常在规则里是合法的。尽管是一个合法程序,因为没有触发这个异常,所以catch里仍然不会执行。
interface Type1 {
void f() throws CloneNotSupportedException;
}
interface Type2 {
void f() throws InterruptedException;
}
interface Type3 extends Type1, Type2 {
}
public class Arcane3 implements Type3 {
public void f() {
System.out.println("Hello world");
}
public static void main(String[] args) {
Type3 t3 = new Arcane3();
t3.f();
}
}
每一个接口都限制了方法f可以抛出的被检查异常集合。一个方法可以抛出的被检查异常集合是它所适用的所有类型声明要抛出的被检查异常集合的交集,而不是合集。因此,静态类型为Type3的对象上的f方法根本就不能抛出任何被检查异常。因此,Arcane3可以毫无错误地通过编译,并且打印Hello world。
总之,第一个程序说明了一项基本要求,即对于捕获被检查异常的catch子句,只有在相应的try子句可以抛出这些异常时才被允许。第二个程序说明了这项要求不会应用到的冷僻案例。第三个程序说明了多个继承而来的throws子句的交集,将减少而不是增加方法允许抛出的异常数量。本谜题所说明的行为一般不会引发难以捉摸的bug,但是你第一次看到它们时,可能会有点吃惊。
3、谜题40 不情愿的构造器
构造方法中抛出异常并不常见,下面的代码就是这样,思考下会打印出什么?
public class Reluctant {
private Reluctant a = new Reluctant();
public Reluctant() throws Exception {
throw new Exception("I'm not coming out");
}
public static void main(String[] args) {
try {
Reluctant b = new Reluctant();
System.out.println("Surprise!");
} catch (Exception ex) {
System.out.println("I told you so");
}
}
}
运行之后,什么也没打印,报错误——StackOverflowError异常(属于Error,不属于Exception,所以catch不能捕捉)。为什么呢?这是因为,当你调用构造器时,实例化变量的初始化操作会先于构造器的程序体运行。在上述代码中,a变量的初始化调用了构造器,而构造器需要调用自身去完成初始化操作,所以就造成了一个递归。
对于一个对象包含与它自己类型相同的实例的情况,并不少见。例如,链接列表节点、树节点和图节点都属于这种情况。你必须非常小心地初始化这样的包含实例,以避免StackOverflowError异常。
总之,实例初始化操作是先于构造器的程序体而运行的。实例初始化操作抛出的任何异常都会传播给构造器。最后,对于我们所设计的类,如果其实例包含同样属于这个类的其他实例,那么对这种无限递归要格外当心。
4、谜题41 域和流
这个想给的结论就是:当你在finally语句块中调用close方法时,要用一个嵌套的try-catch语句来保护它,以防止IOException的传播。更一般地讲,对于任何在finally语句块中可能会抛出的被检查异常都要进行处理,而不是任其传播。
5、操作符
逻辑AND操作符& 条件AND操作符&& 区别:前者必须计算两个操作数之间的与关系 后者当前边的操作数为false时,就直接返回false,不在考虑后边操作数的真假。
逻辑OR操作符| 条件OR操作符|| 区别:前者必须计算两个操作数之间的或关系 后者当前边的操作数为true时,就直接返回true,不考虑后边的。
Java——异常谜题的更多相关文章
- Java异常(三) 《Java Puzzles》中关于异常的几个谜题
概要 本章介绍<Java Puzzles>中关于异常的几个谜题.这一章都是以代码为例,相比上一章看起来更有意思.内容包括:谜题1: 优柔寡断谜题2: 极端不可思议谜题3: 不受欢迎的宾客谜 ...
- Java异常错误的面试题及答案
1) Java中什么是Exception? 这个问题经常在第一次问有关异常的时候或者是面试菜鸟的时候问.我从来没见过面高级或者资深工程师的 时候有人问这玩意,但是对于菜鸟,是很愿意问这个的.简单来说, ...
- java异常面试常见题目
在Java核心知识的面试中,你总能碰到关于 处理Exception和Error的面试题.Exception处理是Java应用开发中一个非常重要的方面,也是编写强健而稳定的Java程序的关键,这自然使它 ...
- Java异常系列
Java异常(一) Java异常简介及其架构 Java异常(二) <Effective Java>中关于异常处理的几条建议 Java异常(三) <Java Puzzles>中关 ...
- 浅谈java异常[Exception]
学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java! 一. 异常的定义 在<java编程思想 ...
- 基础知识《十》java 异常捕捉 ( try catch finally ) 你真的掌握了吗?
本文转载自 java 异常捕捉 ( try catch finally ) 你真的掌握了吗? 前言:java 中的异常处理机制你真的理解了吗?掌握了吗?catch 体里遇到 return 是怎么处理 ...
- Java异常体系及分类
上图是基本的java异常体系结构. 主要分为2大类:Error和Exception 1.Error:描述了Java运行系统中的内部错误以及资源耗尽的情形.应用程序不应该抛出这种类型的对象,一般是由虚拟 ...
- Java异常之自定义异常
哎呀,妈呀,又出异常了!俗话说:"代码虐我千百遍,我待代码如初恋". 小Alan最近一直在忙着工作,已经很久没有写写东西来加深自己的理解了,今天来跟大家聊聊Java异常.Java异 ...
- 第11章 Java异常与异常处理
1.Java异常简介 1.什么是异常异常出现的时候代码会无法正常运行下去,会产生各种问题2.捕捉异常的作用提早发现异常,方便查找问题,并给出解决方法3.Java中的异常1.Java中所有不正常的类都是 ...
随机推荐
- Unity3d 物体沿着正七边形轨迹移动
不对之处,敬请谅解. 1.圆内接正七边形半径 public static float r = 10; 2.存储七个顶点的值 Vector3[] ar = new Vector3[7]; 3.圆心角 s ...
- web开发在线调试
来源: http://www.cnblogs.com/itech/archive/2012/09/23/2698754.html 通常我们开发web时候,使用ie的developertoolgs,或c ...
- .net获取根目录的方法集合
编写程序的时候,经常需要用的项目根目录.自己总结如下 .取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 方法2. ...
- VC2010编译错误
1. cannot convert parameter 1 from 'const char [43]' to 'LPCWSTR' 我是看了这个之后解决问题的~ http://blog.163.com ...
- iOS开发 GET、POST请求方法:NSURLSession篇
NSURLConnection,在iOS 9被宣布弃用,本文不使用NSURLConnection进行网络编程,有兴趣的童鞋可以参考: iOS开发 GET.POST请求方法(NSURLConnectio ...
- Java学习笔记之自定义异常
1.自定义异常类: /** * 自定义异常,只要继承继承Exception类或其子类即可 * @author Administrator * */ public class FileException ...
- linux sort 用法
sort命令是帮我们依据不同的数据类型进行排序,其语法及常用参数格式: sort [-bcfMnrtk][源文件][-o 输出文件]补充说明:sort可针对文本文件的内容,以行为单位来排序. 参 数: ...
- C语言头文件
最近在工作当中遇到了一点小问题,关于C语言头文件的应用问题,主要还是关于全局变量的定义和声明问题.学习C语言已经有好几年了,工作使用也近半年了,但是对于这部分的东西的确还没有深入的思考过.概念上还是比 ...
- [转]ubuntu的which、whereis、locate和find命令
which 只能寻找执行文件 ,并在PATH变量里面寻找. whereis 从linux文件数据库(/var/lib/slocate/slocate.db)寻找,所以有可能找到刚刚删除,或者没有发现 ...
- mapreduce 顺序组合
import java.io.IOException;import java.util.StringTokenizer; import org.apache.hadoop.conf.Configura ...