将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,并且方法名称匹配的某些表达式在这里都不会有用。
如果需要更多信息或问题描述不够充分,请与我们联系。
感谢您阅读我的问题并思考它。
答案 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作为参数或公共方法的返回值。
我使用Optional和Preconditions或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
单例的引用。