NULL参数是不好的做法吗?

时间:2010-12-26 19:28:41

标签: java exception methods null arguments

将NULL参数传递给方法是不好的做法,换句话说,如果我们有允许NULL参数作为有效参数的方法定义,这是不好的做法。

假设我想要两种方法 1.检索所有公司的清单 2.根据过滤器检索公司列表。

我们可以有两种方法,如下所示

    List<Company> getAllCompaniesList();
    List<Company> getCompaniesList(Company companyFilter);

或者我们可以有一个方法

    List<Company> getCompaniesList(Company companyFilter);

这里是第二种情况,如果参数为NULL,则方法返回所有公司的列表。

除了良好实践的问题,实际上我还会看到后面的方法中的另一个问题,这将在下面解释。

我正在实现Spring AOP,其中我希望对像这样的参数进行一些检查 1.参数是否为NULL? 2.是集合0的大小?

在某些情况下,我们根本无法使用null参数,例如方法

    void addBranches(int companyId, List<Branch>);

通过定义类似下面的方法

,使用Spring AOP可以很好地执行此检查
@Before(argNames="args", value="execution(* *)")
void beforeCall(JoinPoint joinPoint ,Object[] args )
{ 
           foreach(Object obj in args)
           {
                 if(obj == NULL)
                 {
                     throw new Exception("Argument NULL");
                 } 
           }   
}

但是我面临的问题是因为我已经定义了一些方法,这些方法应该接受一个方法的多个功能的NULL参数,如上面提到的方法List getCompaniesList(Company companyFilter); 所以我不能对所有方法统一应用AOP,并且方法名称匹配的某些表达式在这里都不会有用。

如果需要更多信息或问题描述不够充分,请与我们联系。

感谢您阅读我的问题并思考它。

5 个答案:

答案 0 :(得分:18)

如果有太多重载方法,那很好。因此,不是拥有所有参数组合,而是允许其中一些参数null。但是如果你这样做,请用

明确记录
@param foo foo description. Can be null

在你的情况下,我有两种方法,第一种方法用null参数调用第二种方法。它使API更有用。

没有严格的行停止重载以及从哪里开始依赖可空参数。这是一个偏好问题。但请注意,因此使用最多参数的方法将允许其中一些可以为空,所以请记录下来。


另请注意,处理多个构造函数参数的首选方法是通过Builder。所以而不是:

public Foo(String bar, String baz, int fooo, double barr, String asd);

其中每个参数都是可选的,您可以:

Foo foo = new FooBuilder().setBar(bar).setFooo(fooo).build();

答案 1 :(得分:14)

我使用了一个非常简单的规则:

绝不允许null作为参数或公共方法的返回值。

我使用OptionalPreconditions或AOP来强制执行该规则。 在NPE或奇怪的行为之后,这个决定已经为我节省了大量的时间。

答案 2 :(得分:6)

这是常见的做法,但有一些方法可以使您的代码更清晰 - 有时避免空值检查,或者将它们移动到别处。查找空对象模式 - 它可能正是您所需要的:http://en.m.wikipedia.org/wiki/Null_Object_pattern?wasRedirected=true

答案 3 :(得分:3)

规则是:界面简单,实现复杂。

关于API的设计决策应该考虑客户端代码可能如何使用它。如果你希望看到

getAllCompaniesList(null);

if (companyFilter == null) {
    getAllCompaniesList();
} else {
    getAllCompaniesList(companyFilter);
}
那时你做错了。如果可能的用例是客户端代码在编写时要么有或没有过滤器,你应该提供两个入口点;如果在运行时可能没有做出该决定,则允许空参数。

答案 4 :(得分:0)

另一种可行的方法可能是使CompanyFilter接口使用companyIsIncluded(Company)方法接受Company并返回true或false来说明是否应该包含任何公司。 Company可以实现该接口,以便companyIsIncluded方法的行为可以镜像equals(),但可以轻松拥有CompanyFilter.AllCompanies方法始终返回true的单companyIsIncluded()。使用这种方法,不需要传递空值 - 只需传递对AllComapnies单例的引用。