当我编码时,我常常问自己同样的问题:
我是否必须验证所有参数都不为空?所以,在每种方法中,我都会有类似的东西:
if (arg1 == null)
{
throw FooException("...");
}
if (arg2 == null)
{
throw FooException("...");
}
如果没有,在哪种情况下更可取?
最佳做法是什么?
答案 0 :(得分:2)
一如既往,这取决于。
如果你正在编写一个供其他团队/组织使用的API,那么通过对公共功能进行前置条件检查的防御性编程可以真正帮助你的用户;当使用外部库时,一个有意义的错误消息,比如'传递给foo()的参数不应该为null'比从某个内部类抛出的NullPointerException更好。
但是,在API之外,我认为这样的检查会使代码混乱太多。无论如何,抛出的NullPointerExceptions通常很容易跟踪调试器。在支持它们的语言中,您可以考虑使用断言 - 它们的语法通常不那么麻烦,您可以在生产时关闭它们,这样检查就不会降低性能。答案 1 :(得分:1)
不幸的是,是的。你应该检查所有的论点。理想情况下,如果您使用良好的设计实践进行编码,则一个函数最多不应超过4或5个参数。
话虽如此,我们应该始终检查函数入口中的空值并抛出适当的异常或IllegalArgumentException(我的收藏)。
但是,永远不应该将NULL传递给函数,并且永远不应该返回NULL。听起来很简单但它会节省大量代码和错误。也可以查看NULL Design Pattern。
答案 2 :(得分:0)
取决于,如果你想要不同的例外,我猜你必须在你可能获得空值的所有场合都这样做。另一种方式是用户DATATYP.TryParse()。仔细看看。
希望它有所帮助。
答案 3 :(得分:0)
因为你无论如何都要抛出异常,不验证它们可能只会导致nullpointerexception或类似的东西。我不完全确定自己最好的做法是什么。
答案 4 :(得分:0)
理想情况下,在执行可能修改与所述参数关联的任何状态或数据的任何操作之前,应始终验证任何参数。最好以早期和可管理的方式(通过抛出异常)进行失败,而不是最终导致不一致的状态/数据,然后还必须解决。
您的方法期望某些数据存在,在某些情况下,应该可以安全地假设它实际存在(例如在私有方法中,从其他验证输入的方法调用)。但总的来说,我会建议验证参数:
可能值得看一下之前的this StackOverflow问题。
答案 5 :(得分:0)
我觉得这主要归结为常识,而且有点偏向于个人偏好。
正如其他人所提到的,如果它是公共API,那么您希望尽可能提供明确的错误消息,因此最好在使用它们之前检查参数,并根据您的示例将消息抛出异常。
如果是内部代码,那么还有两个其他选择:使用断言,或者不需要验证并依赖于调试。根据经验,如果代码是我希望其他开发人员将调用的,或者如果条件足够精细以至于调试它可能会很麻烦,我会将断言放入其中。否则,我只会让它失败。
有时您可以使用Null Object pattern来避免此问题。如果它是公共API,我仍然倾向于包括支票。