Java:构造函数中抛出异常,我的对象仍然可以创建吗?

Posted

技术标签:

【中文标题】Java:构造函数中抛出异常,我的对象仍然可以创建吗?【英文标题】:Java: Exception thrown in constructor, can my object still be created? 【发布时间】:2011-08-20 01:41:20 【问题描述】:

你能告诉我在构造函数中抛出异常并且对象不为空的情况。我的意思是对象的某些部分已创建,而另一部分未创建。像这样

public Test()
name = "John";
// exception
// init some other data.

我知道在这种情况下对象测试将为空,但可能是对象测试不能为空的情况(删除异常块不回答:))?

【问题讨论】:

只有当你在构造函数中捕捉到你的异常时。我的意思是,如果它不会被进一步扔给调用者。 【参考方案1】:

如果类实例创建表达式的限定符和参数的评估正常完成,并且有足够的空间来创建对象,则总是会创建一个新对象。构造函数是否抛出异常无关紧要;仍然会创建一个对象。但是,在这种情况下,类实例创建表达式不会正常完成,因为它会传播异常。

但是,您仍然可以获得对新对象的引用。考虑以下几点:

public class C 
    static C obj; // stores a "partially constructed" object
    C() 
        C.obj = this;
        throw new RuntimeException();
    
    public static void main(String[] args) 
        C obj;
        try 
            obj = new C();
         catch (RuntimeException e) 
            /* ignore */
        
        System.out.println(C.obj);
    

在这里,在抛出异常之前,对新对象的引用存储在其他地方。如果你运行这个程序,你会看到这个对象确实不是空的,虽然它的构造函数没有正常完成。

【讨论】:

哇,好答案。从来没有想过这样的对象构造。我知道子类(重新)实现一些超类方法的类似问题,因此可能会暴露部分构造的对象。但是,在这种情况下,C 实例是完全构造的 - 不可能(例如)向 C 类添加最终字段,将其初始化为字段初始化,但在这种情况下还没有初始化该字段。 我也写过同样的测试 :) 谢谢。 不仅看到对象不为空,我们还可以从 C.obj 中调用方法;​​【参考方案2】:

没有。看客户端代码:

Test myObj = null;
try 
 myObj = new Test();
 catch(MyException e) 
  System.out.println("" + myObj);

这里,发生异常时,不执行'='操作。您的代码直接进入 catch 块,而 myObj 保持 null

【讨论】:

-1:对象没有赋值,但还是被创建了,看其他答案。 丹尼尔,谁不同意?我写的东西是一样的:分配没有发生。【参考方案3】:

没有。如果在对象实例化过程中发生异常,则不会创建。

不管怎样,你会写吗?

MyObject obj = new MyObject();
// This code will not be reachable in case of an Exception

或:

MyObject obj = null;
try 
    obj = new MyObject();
 catch (AnyException e) 

// Here, either obj is created correctly, or is null as an Exception occurred.

【讨论】:

是的,我知道,我已经测试过这种情况,但很想知道,当对象不为空时,“神奇”情况会是什么,或者可能是什么。 正如Gasan上面所说的“只有当你在构造函数中捕获你的异常。我的意思是如果它不会被进一步抛出给调用者”我希望它是有意义的【参考方案4】:
public Test()   
    name = "John"; 
    try 
        // exception 

        // init some other data.
     catch(AnyException e) 
        // catch
    

上述代码符合您的期望。

【讨论】:

以上是关于Java:构造函数中抛出异常,我的对象仍然可以创建吗?的主要内容,如果未能解决你的问题,请参考以下文章

在构造函数中抛出 ArgumentNullException?

main前后的异常处理

从匿名内部类的构造函数中抛出异常

不要在构造函数中抛出异常

java中 方法中抛出异常处理方法

C++异常处理的编程方法(阿愚,整整29集)