构造函数会在 Java 中引发异常吗?
2022-08-31 05:47:10
是否允许构造函数引发异常?
是的,构造函数可以引发异常。通常,这意味着新对象立即符合垃圾回收的条件(当然,它可能在一段时间内不会被收集)。但是,如果“半构造”对象在构造函数中更早地使自身可见(例如,通过分配静态字段或将自身添加到集合中),则“半构造”对象可能会保留下来。
在构造函数中抛出异常时要小心的一件事是:因为调用方(通常)将无法使用新对象,构造函数应该小心避免获取非托管资源(文件句柄等),然后在不释放它们的情况下引发异常。例如,如果构造函数尝试打开 a 和 a,并且第一个成功,但第二个失败,则应尝试关闭第一个流。当然,如果它是一个子类构造函数,它会引发异常,这将变得更加困难......这一切都变得有点棘手。这通常不是问题,但值得考虑。FileInputStream
FileOutputStream
是的,它们可以引发异常。如果是这样,它们将仅部分初始化,如果不是最终的,则受到攻击。
以下内容来自安全编码指南 2.0。
非最终类的部分初始化实例可以通过终结器攻击进行访问。攻击者覆盖子类中受保护的 finalize 方法,并尝试创建该子类的新实例。此尝试失败(在上面的示例中,ClassLoader 构造函数中的 SecurityManager 检查会引发安全异常),但攻击者只是忽略任何异常并等待虚拟机对部分初始化的对象执行最终确定。发生这种情况时,将调用恶意的 finalize 方法实现,使攻击者能够访问此内容,并引用正在完成的对象。尽管该对象仅部分初始化,但攻击者仍然可以在其上调用方法(从而绕过 SecurityManager 检查)。