Language agnostic 尽早抛出异常是否是一种好的做法?

Language agnostic 尽早抛出异常是否是一种好的做法?,language-agnostic,exception,Language Agnostic,Exception,今天我遇到了以下情况:(“伪代码”) 现在,如果调用者使用包含null项的数组调用workinarray,调用者将因为workanitem而得到NullPointerException 但是我可以在workinarray中插入一个额外的签入,换句话说,可以更快地发现问题 (请注意,这是一个简单的示例,在实际应用程序中,这可能不太明显) 在专业方面,我认为额外的检查可以提供更多的高级诊断信息。而且,早早失败总是一件好事 相反,我会问自己“如果我这样做了,我是否也应该验证传递到编程语言核心API中的

今天我遇到了以下情况:(“伪代码”)

现在,如果调用者使用包含
null
项的数组调用
workinarray
,调用者将因为
workanitem
而得到
NullPointerException

但是我可以在
workinarray
中插入一个额外的签入,换句话说,可以更快地发现问题

(请注意,这是一个简单的示例,在实际应用程序中,这可能不太明显)

在专业方面,我认为额外的检查可以提供更多的高级诊断信息。而且,早早失败总是一件好事

相反,我会问自己“如果我这样做了,我是否也应该验证传递到编程语言核心API中的每个参数,并抛出完全相同的异常?”


什么时候尽早抛出异常,什么时候让被调用方抛出异常,有什么经验吗?

在循环处理这样的项的情况下,有一件事肯定会让我想先预先验证整个项数组;如果在抛出异常之前处理某些项是不好的,则会留下任何未处理的剩余项


除非使用某种事务机制包装代码,否则我通常希望在开始处理集合中的项之前确保它们是有效的。

在本例中,worknitem方法关心项是否为null。workinarray方法不关心项是否为null,因此IMO不应该验证任何项是否为null。WorkInItem方法很重要,因此应该执行检查


<>我也会考虑从WorkItIt项目中抛出一个更合适的异常类型。NullPointerException(或在C#中为NullReferenceException)通常表示方法操作中存在某些意外缺陷。在C#中,我更倾向于抛出一个ArgumentNullException,其中包含null参数的名称。这更清楚地表明WorkInItem无法继续,因为它无法处理接收空参数的问题。

提前失败并不总是一件好事。有时,积累错误并在事后向用户提交报告会更好,尤其是在批量处理大量数据时。死掉的程序不会说谎。换句话说,早期出错的程序不能意外地覆盖重要信息。此外,还要考虑断言和前提条件@拉斯曼:所有的概括都是错误的。即使是这个:)+1。如果您正在更改数据并且没有可用的事务,请先检查(如果只是一个没有副作用的计算,请不要太担心)。在循环的情况下,我也一直在想(而且从不执行)不仅仅是抛出一个表示“此元素不好”的异常,而是收集一个表示“元素1、5、7不好”的异常中的所有错误;它增加了一点复杂性,但如果继续处理其余元素,然后返回异常集合(可能是在具有集合成员的自定义异常中),这可能是一个很好的选择或者包含所有错误信息的异常,只允许修复“坏”项并重试。+1我同意预验证是一个加号,即使它涉及复杂结构的检查@DR:试着用模拟品尝的方式来思考这个问题:如果我想模拟
workInItem()
并只检查
workInArray()
的功能,那么行为将取决于哪个位置包含
null
元素。复杂。如果验证与业务逻辑分离,测试就更简单了。“workinarray方法不关心项是否为null”。好的,如果第三项为null,那么前两项就已经被处理了,如果您没有事务,这可能会留下一点不一致。另一方面,无论您事先做了多少错误检查,都可能发生这种情况。@Thilo-当然正确。这就是抽象解决方案崩溃的地方,真正的业务需求开始决定什么是必要的。某些应用程序可能需要处理批处理中的所有项目,或者根本不处理任何项目,而其他应用程序可能会从部分成功中受益。最终答案取决于应用程序的业务规则。
class MyClass {

    public void workOnArray(Object[] data) {
        for (Object item : data) {
            workOnItem(item);
        }
    }

    public void workOnItem(Object item) {
        if (item == null) throw new NullPointerException();
    }
}