【问题标题】:When & how should constructors enforce limits on instance variables?构造函数应该何时以及如何对实例变量实施限制?
【发布时间】:2014-10-01 08:57:34
【问题描述】:

我是编程新手,正在学习 Java 作为我的第一门 oo 语言,通过阅读 David J. Eck 的 Java 编程简介并在遇到困难时阅读论坛帖子。

我的问题可以被认为是 Java Class Constructor Parameters with range limits 的后续问题,它处理将 Hour 类的构造函数的 int 参数限制为 0 到 23。

上述问题的答案提到抛出 Instantiation Exception 或 IllegalArgumentException,但不清楚哪种方式更好。

另外,如果有的话,与验证代码相关的开销是否合理?

【问题讨论】:

  • 作为记录,如果值超出特定范围(0-255 或 0.0-1.0,取决于使用的构造函数),某些 java.awt.Color 类构造函数会抛出 IllegalArgumentException

标签: java oop methods contracts


【解决方案1】:

只抛出IllegalArgumentException是正确的。

抛出表明一个方法被传递了一个非法或不适当的参数。

InstantiationException 用于不同的目的。

当应用程序尝试使用类Class 中的newInstance 方法创建类的实例,但无法实例化指定的类对象时引发。实例化可能因多种原因而失败,包括但不限于:

  • 类对象表示抽象类、接口、数组类、原始类型或void

  • 该类没有空构造函数

InstantiationException 与反射调用未能调用构造函数有关,但IllegalArgumentException 表示构造函数(或方法)已成功调用,但代码块确定参数不合适。

最好有一点开销来验证传入构造函数(和方法)的参数。运行不正常的程序或类比运行正常的程序更糟糕,而且速度可能慢得可以忽略不计。

【讨论】:

    【解决方案2】:

    关于开销

    我认为没有规则,但我认为,一般来说,如果您的对象需要一个外部参数才有意义,那么在构造函数中强制执行这样的事情是有意义的,就像 java.awt.Color 对象一样@TNT 在 cmets 中告诉。

    如果您有一些只能使用构造函数提供的参数创建的有状态对象,而没有其他相同参数的设置器,这也是有意义的。

    关于例外情况

    我不能比@rgettman 做得更好 ;-) 他的回答对我来说完全有道理

    【讨论】:

      【解决方案3】:

      一般来说,我喜欢确定传递到我的代码中的对象是有效的。如果班级本身已经强制执行,我可以确定而无需再次检查。基于此,我认为至少在您的类和构造函数是公共的或可被大量代码访问的情况下,仔细验证您的构造函数参数并强制执行您的不变量是一个好主意。

      如果你有一个小包和一个只在有限的上下文中使用的类,或者甚至是一个私有内部类,那么在验证方面可以放松一些。

      我会使用 IllegalArgumentException 或从它派生的东西进行验证,因为这种类型可以更清楚地说明发生了什么,并且错误在于调用者。

      【讨论】:

        猜你喜欢
        • 2014-01-12
        • 2023-03-02
        • 1970-01-01
        • 2010-12-31
        • 1970-01-01
        • 1970-01-01
        • 2012-10-30
        • 2019-03-10
        • 1970-01-01
        相关资源
        最近更新 更多