为什么没有arg构造函数在无效状态下被实例化



我一直在寻找JavaBean的优点和缺点。在缺点部分,我遇到了这个:

具有null构造函数的类会在无效状态下被实例化维基百科-JavaBeans

这到底意味着什么?这种情况如何适用于具有参数实参的构造函数?

如果这样的类是由开发人员手动实例化的(而不是由某种框架自动实例化),那么开发人员可能不会意识到该类的实例化不正确。

JavaBean框架可以对实例化的JavaBean执行自动操作,例如,通过调用方法、将参数传递给常规方法等,这取决于JavaBean的设计目的,以及框架在其控制下如何处理JavaBean。

编译器无法检测到这样的问题,即使有文档记录,也不能保证开发人员会看到文档。

重新表述:"开发人员并不总是勤奋,即使他们勤奋,他们也不总是正确的。"

为自动化工具的消费而明确设计的组件并不总是为实际用户的消费而精心设计的。

考虑java.net.URL

假设它有一个null构造函数,以及一个用于实际url字符串、端口等的setter。当使用null构造函数进行设置时,它将处于无效状态,任何试图使用该url对象的人都会遇到问题。

URL显然没有null构造函数。我使用这一点只是为了强调一点,即对于一些对象,使用null构造函数可以在无效状态下初始化它们

考虑一个简单类,它有一个名为name的简单String属性。它可能有一个public String getName()方法来获取属性的值。尽管该方法的签名表示它返回对String对象的引用,但类的设计可能比这更具限制性。例如,设计可能会规定名称不能为null,不能为空,并且必须以大写字符开头,并且必须是唯一的。该类中任何被观察到具有不符合所有这些限制的名称的对象都将无效。

构造函数的工作是在初始状态下设置一个新对象,该对象必须是有效状态。如果没有向构造函数提供有关如何构造对象的附加信息,构造函数就不可能满足某些类型的值限制。

没有参数的构造函数不能得到这些信息,因此Java Bean的设计不能应用某些类型的限制,或者只有在构造函数不受这些限制的情况下才能应用。免除它们实际上意味着允许构造函数创建无效对象。

由null构造函数创建的对象不会为其任何属性设置值。如果框架设置了它,它可能会知道在使用对象之前需要将哪些属性设置为什么类型的值。然而,不熟悉对象意图的程序员可能不知道或忘记将属性设置为有效值。即使有文档规定需要为哪些参数设置哪些值,人类程序员也可能不会阅读该文档或记住遵守所有规则。

例如,在以下代码中,如果对象"data"未设置为有效的枚举类型(如null),则将引发InvalidObjectException。

Object toJavaTypeData(Object data)
throws OpenDataException, InvalidObjectException {
try {
    return Enum.valueOf(enumClass, (String) data);
} catch (IllegalArgumentException e) {
    // missing enum constants
    final InvalidObjectException ioe =
        new InvalidObjectException("Enum constant named " +
        (String) data + " is missing");
    ioe.initCause(e);
    throw ioe;
}

}

最新更新