根据JLS:如果命名类的实例变量初始化程序或实例初始值设定项可以抛出一个已检查的异常类,那么这是一个编译时错误,除非在每个构造函数的throws子句中显式声明了该异常类或其一个超类.它的类和类至少有一个显式声明的构造函数.
所以,如果我这样做 -
class A{
{
throw new FileNotFoundException();
}
public A() throws IOException{
// TODO Auto-generated constructor stub
}
}
Run Code Online (Sandbox Code Playgroud)
这给出了编译时错误"初始化程序必须正常完成"
而
class A{
{
File f=new File("a");
FileOutputStream fo=new FileOutputStream(f);
fo.write(3);
}
public A() throws IOException{
// TODO Auto-generated constructor stub
}
}
Run Code Online (Sandbox Code Playgroud)
此代码不显示任何编译时错误.即使我在构造函数中声明了throws子句,为什么前面的代码不能编译?
应该存在一些条件,使得初始化器能够真正完成而没有任何异常。
就你的情况而言,这是不可能发生的。
尝试:
if(/*condition-to-fail*/) {
/*Not always, only when something is wrong. Compiler knows that.*/
throw new FileNotFoundException();
}
Run Code Online (Sandbox Code Playgroud)
更新:
下面的语句实际上抛出了异常。
throw new FileNotFoundException();
Run Code Online (Sandbox Code Playgroud)
因此,无论任何条件,你的程序执行总是在那里结束。
而在以下内容中——
FileOutputStream fo = new FileOutputStream(f);
Run Code Online (Sandbox Code Playgroud)
构造函数FileOutputStream(File)并不总是抛出该异常。
中的 throws 子句public FileOutputStream(File file) throws FileNotFoundException只是说它可能会抛出该异常,并且只有在运行时未找到文件时才会执行此操作,否则不会。