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

Java解惑4 40不情愿的构造器

尽管在一个方法声明中看到一个throws子句是很常见的,但是在构造器的声明中看到一个throws子句就很少见了。下面的程序就有这样的一个声明。那么,它将打印出什么呢?
public class Reluctant {
private Reluctant internalInstance = 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");
}
}
}
main方法调用了Reluctant构造器,它将抛出一个异常。你可能期望catch子句能够捕获这个异常,并且打印I told you so。凑近仔细看看这个程序就会发现,Reluctant实例还包含第二个内部实例,它的构造器也会抛出一个异常。无论抛出哪一个异常,看起来main中的catch子句都应该捕获它,因此预测该程序将打印I told you应该是一个安全的赌注。但是当你尝试着去运行它时,就会发现它压根没有去做这类的事情:它抛出了StackOverflowError异常,为什么呢?
与大多数抛出StackOverflowError异常的程序一样,本程序也包含了一个无限递归。当你调用一个构造器时,实例变量的初始化操作将先于构造器的程序体而运行[JLS 12.5]。在本谜题中, internalInstance变量的初始化操作递归调用了构造器,而该构造器通过再次调用Reluctant构造器而初始化该变量自己的internalInstance域,如此无限递归下去。这些递归调用在构造器程序体获得执行机会之前就会抛出StackOverflowError异常,因为StackOverflowError是Error的子类型而不是Exception的子类型,所以catch子句无法捕获它。
对于一个对象包含与它自己类型相同的实例的情况,并不少见。例如,链接列表节点、树节点和图节点都属于这种情况。你必须非常小心地初始化这样的包含实例,以避免StackOverflowError异常。
至于本谜题名义上的题目:声明将抛出异常的构造器,你需要注意,构造器必须声明其实例初始化操作会抛出的所有被检查异常。下面这个展示了常见的“服务提供商”模式的程序,将不能编译,因为它违反了这条规则:
public class Car {
private static Class engineClass = ...;
private Engine engine =
(Engine)engin


相关文档:

Java解惑2 28循环者

下面的谜题以及随后的五个谜题对你来说是扭转了局面,它们不是向你展示某些代码,然后询问你这些代码将做些什么,它们要让你去写代码,但是数量会很少。这些谜题被称为“循环者(looper)”。你眼前会展示出一个循环,它看起来应该很快就终止的,而你的任务就是写一个变量声明,在将它作用于该循环之上时,使得该 ......

java 容器类 小结 troy

JAVA的容器---List,Map,Set
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
  Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 Collection允许相 ......

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被从左移入到由移位操作而空出来的位上,即使被移位的负数也是如此。
这个循环比前面三个循环要稍微复杂一点,因为其循环体非空。在其循环题中, ......
© 2009 ej38.com All Rights Reserved. 关于E健网联系我们 | 站点地图 | 赣ICP备09004571号