如何"reject"实例化类

How "reject" instancing a class

本文关键字:实例化 reject 如何      更新时间:2023-10-16

例如,

public class Test {
    Test() {
    if(xxx)//do some check here
        //reject instancing class test.
    }
}

我想我可以抛出一个例外来拒绝它,还有其他方法吗?我不确定实例化被拒绝会产生什么影响,但我认为一种自然的方式是:

Test test = new Test();//return null here indicating instancing rejected.

我希望java和C++都应该有这个"拒绝"特性。

如果您想返回null,可以使用Factory模式。例如,您可以编写Test test = TestFactory.CreateTest();,而不是Test test = new Test();,并在TestFactory.CreateTest中实现所需的所有检查。

new Test()总是返回Test的非null实例(至少在Java中是这样)。

您不能从构造函数返回null,但您可以(按照您的建议)抛出异常。

语言中没有这样的功能,但有两种标准的实现方法:

  • 第一个是抛出异常。你在帖子中暗示了这一点。调用方需要预期此异常,并做好处理准备
  • 第二种是工厂方法。如果由于任何原因未能实例化您的类,它可能会返回null。调用方需要准备好处理来自工厂方法的null返回

在这两个选项之间做出选择并不容易。指导原则是,如果拒绝实例化是异常情况,例如编程或配置错误,则执行异常路线。如果拒绝将定期发生,例如因为某些资源暂时不可用,则采用工厂方法。当然,这些规则也有例外,所以请用你最好的判断。

是的,如果无法创建类的实例,则应该抛出异常。

我想我可以抛出一个异常来拒绝它

的确,从构造函数抛出异常将销毁所有子对象(如果使用继承)和已经初始化的成员。这是中止对象构造的首选方式。

还有别的办法吗?

唯一的其他方法是初始化为伪状态,并要求客户端代码检查构造函数是否使用专用方法成功运行。由于客户很容易忘记这样的电话,我真的不推荐这种方法。

关于这个"解决方案":

Test test = new Test();//return null here indicating instancing rejected.

没有办法强制new从构造函数内部返回一个空指针,所以这是不可行的。您可以使用另一种方法进行模拟,例如:

class Test
{
    Test (...); // constructor that receives prepared arguments.
public:
     static Test * create (...)
     {
         // prepare arguments...
         if (successful) {
             return new Test(prepared_arguments);
         }
         return 0;
     }
};

在你的代码中使用这个作为:

Test * test = Test::create(...);
if (!test) {
     // handle error.
}

但是您仍然可以忘记检查空指针。

首选方法是抛出异常。它更简单,总是有效的,并且需要更少的打字。

在C++中,您不需要返回指针,请考虑:

Test t; // run the constructor

因此,使用异常或工厂模式是拒绝通知的唯一方法。