实例初始化操作是先于构造器的程序体而运行的。
public class Reluctant {
private Reluctant internalInstance = new Reluctant(); //tag1
public Reluctant() throws Exception { //tag2
throw new Exception("I'm not coming out");
}
public static void main(String[] args) {
try {
Reluctant b = new Reluctant(); //tag3
System. out.println("Surprise!" );
} catch (Exception ex) {
System. out.println("I told you so" );
}
}
}
这里,按照 JLS 12.5 的说法:
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
this
), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.this
). If this constructor is for a class other than Object
, then this constructor will begin with an explicit or implicit invocation of a superclass constructor (using super
). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.如上,域的实例化(第4步)将在构造器执行(第5步)之前。如此在实例化类时,会出现:
如此递归调用绵绵无绝期,最后抛出 StackOverflowError 的异常,这个异常不是 Exception 类型,catch 语句是不能捕获的。
参:
JLS 12.5: http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5