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

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

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

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

【问题讨论】:

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

标签: java exception constructor logic


【解决方案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
    }
}

上述代码符合您的期望。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    相关资源
    最近更新 更多