构造函数允许抛出异常吗?
是的,构造函数可以抛出异常。通常这意味着新对象立即有资格进行垃圾收集(当然,尽管它可能在一段时间内不会被收集)。对于“半构造”的对象来说,如果它在构造函数的早期使自己可见(例如,通过分配一个静态字段,或将自己添加到一个集合),那么它是有可能被保留的。
One thing to be careful of about throwing exceptions in the constructor: because the caller (usually) will have no way of using the new object, the constructor ought to be careful to avoid acquiring unmanaged resources (file handles etc) and then throwing an exception without releasing them. For example, if the constructor tries to open a FileInputStream and a FileOutputStream, and the first succeeds but the second fails, you should try to close the first stream. This becomes harder if it's a subclass constructor which throws the exception, of course... it all becomes a bit tricky. It's not a problem very often, but it's worth considering.
是的,构造函数允许抛出异常。
但是,在选择异常时要非常明智——检查异常还是未检查异常。未检查的异常基本上是RuntimeException的子类。
在几乎所有的情况下(我找不到这种情况的异常),您都需要抛出一个受控异常。原因是未检查的异常(如NullPointerException)通常是由于编程错误(如没有充分验证输入)。
受控异常提供的好处是,程序员被迫在他的实例化代码中捕获异常,从而意识到创建对象实例可能会失败。当然,只有代码复查才能发现吞下异常的糟糕编程实践。
是的,它们可以抛出异常。如果是这样,它们将只被部分初始化,如果是非最终的,则会受到攻击。
以下内容摘自安全编码指南2.0。
Partially initialized instances of a non-final class can be accessed via a finalizer attack. The attacker overrides the protected finalize method in a subclass, and attempts to create a new instance of that subclass. This attempt fails (in the above example, the SecurityManager check in ClassLoader's constructor throws a security exception), but the attacker simply ignores any exception and waits for the virtual machine to perform finalization on the partially initialized object. When that occurs the malicious finalize method implementation is invoked, giving the attacker access to this, a reference to the object being finalized. Although the object is only partially initialized, the attacker can still invoke methods on it (thereby circumventing the SecurityManager check).
是的,它可以抛出一个异常,你也可以在构造函数的签名中声明,如下例所示:
public class ConstructorTest
{
public ConstructorTest() throws InterruptedException
{
System.out.println("Preparing object....");
Thread.sleep(1000);
System.out.println("Object ready");
}
public static void main(String ... args)
{
try
{
ConstructorTest test = new ConstructorTest();
}
catch (InterruptedException e)
{
System.out.println("Got interrupted...");
}
}
}
推荐文章
- 使用Enum实现单例(Java)
- RabbitMQ与通道和连接之间的关系
- buildSessionFactory()配置方法在Hibernate中已弃用?
- Spring MVC -如何获得所有的请求参数在一个地图在Spring控制器?
- 如何在Java中按两个字段排序?
- 文件之间的差异。路径中的分隔符和斜杠
- 为什么不使用异常作为常规的控制流呢?
- 在方法参数中使用NotNull注释
- Spring MVC中处理可选参数的@RequestParam
- Tomcat:如何查找正在运行的Tomcat版本?
- “java”、“javaw”和“javaws”之间有什么区别?
- 将Date对象转换为日历对象
- 在Java中保存最后N个元素的大小有限的队列
- 如何运行一个类从Jar不是主类在其清单文件
- 使arrayList.toArray()返回更具体的类型