【问题标题】:Instance variable verification实例变量验证
【发布时间】:2013-09-26 17:47:54
【问题描述】:

阅读有效的java,它提到我们需要验证方法参数作为一种好习惯,公共方法抛出异常,私有方法断言。但是,我们是否需要对实例变量采取任何措施。

EG:(不要把例子当作用例,主要问题是Do I need to validate instance var or Not ?。例子只是用来解释我的意思。)

class Tree {

   private Node root;

   public doSomething() {
      TreeNode node = root;
   }
}

现在假设root 从未被初始化并且doSomething() 被直接调用,这将导致NullPtrException。

Do we need to guard against it ? If yes then how ? If no then why not ?

【问题讨论】:

  • 只有在doSomething 中使用节点才会抛出 NullPointerException 你的例子是模糊的
  • 为什么不直接使用正常的异常处理?
  • 也许你可以在分配它之前使用 instanceof 运算符检查 root 是否是 TreeNode 的实例...
  • @All,请关注主要问题而不是示例。
  • @dganesh2002 从 OP 所说,问题不是 CastTypeException,而是 root 可能为 null 的事实

标签: java effective-java


【解决方案1】:

怎么样:

if (root == null) {
    throw new SomethingException();
}
TreeNode node = root;

简单地说,只需对根变量执行 null 检查,如果为 null,则执行相应的代码来修复该问题或为其抛出一个新异常。

【讨论】:

  • 似乎同样的问题仍然存在,仍然抛出异常,这似乎只是重命名异常。除非有更进一步的代码也可以抛出 NullPointer 并且这是为了确定抛出它的原因,否则捕获 NullPointer 并处理它似乎更容易。
  • 我在推理中进行了编辑,但是是的,它或多或少是“把你需要的东西放在这里”的占位符。无论是自定义异常、空指针,还是初始化变量的代码,都取决于 OP 的设计。
  • @Rogue 所以你的答案是每个实例变量都需要验证?
  • 就我个人而言,我会确保全局变量是通过类构造函数设置的,但是如果您知道它们不会在那时被初始化,那么您应该检查全局变量是否为 null .
【解决方案2】:

检查方法参数的既定做法可以推广到检查类的正确用法。在给定的示例中,当实例变量 root 尚未初始化时,调用方法 doSomething() 是非法的。

如果你想要一个最佳实践规则,一般不是检查实例变量,而是检查一个类的某个使用协议是否被遵守。 (除非以不需要遵循特定协议的方式编写类,这通常是更好的选择。)这种检查当然通常涉及检查实例变量。

与在否定方法参数检查后抛出IllegalArgumentException 相比,违反协议应导致IllegalStateException

在给定的示例中,应该抛出 IllegalStateException,因为该实例不处于可以调用 doSomething() 的状态。

【讨论】:

    【解决方案3】:

    将实例变量的任何验证代码移至构造函数和设置器,以便在设置或更改它时检查它,如果在更改之前输入无效,则抛出任何异常。

    对于完全构造的对象,这使实例变量始终处于有效状态,因此您不必在其他任何地方进行额外的验证。

    【讨论】:

      猜你喜欢
      • 2019-06-03
      • 2012-12-23
      • 2016-09-03
      • 2014-09-21
      • 2019-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多