给定这样的通用接口(这不是我的实际情况,而是最低示例):
/** Generic interface for unary functions on strings. */
public interface StringTransformer {
/**
* Transform the given non-null string.
* @param x string to be transformed
* @return transformed string
* @throws NullPointerException if x is null
*/
String apply(String x);
}
假设我有一个实现返回常数值,而不管传递的参数如何:
public class EmptyAllStrings implements StringTransformer {
public String apply(String x) {
return "";
}
}
我的疑问是,如果参数为 null
,添加支票是否是一个好主意,即使在这种情况下不重要。
public String apply(String x) {
Objects.checkNotNull(x);
return "";
}
对检查的点:
-
null
可以在已知的特定类别的情况下使用 - 更少的代码
支持检查的点:
- 有效地符合接口Javadoc
- 即使使用
null
-使用null
的错误,也可能有助于发现CC_3相关的错误
是否有或多或少的"权威"指南建议在这种情况下这两个选项之一?
我不明白为什么您想在此处检查null
。这个想法是,NullPointerException
是由JVM抛出的,而不是Java代码...如果有的话,我希望为这种支票扔IllegalArgumentException
(尽管我与有不同意见的人一起工作,所以ymmv)。
在这里,您有效地从一无所有地返回了一些东西;您不知道周围代码是否需要null
检查。这不是该代码的责任。
和javadoc评论的意思是"可能会抛出异常",而不是保证" IMO。
我实际上已经看过几次了,我总是有一个问题"为什么?",基本上是不良的发展,因为其他人说的不是代码应该抛出NPE这就是JVM启动的地方,NPE是开发人员错误。拥有一个始终返回同一件事的实现方法是毫无意义的,不需要删除,否则提供正确的实现,并进行零检查(如果有机会可以为null进行null),将firlegalargumentex扔进在其他地方正确。
我相信问题的根是在接口的文档中存在 @throws NullPointerException
。NullPointerException
应用于编程错误,但是在这里您只是说明合同,而不是实现。让实施类决定如何处理空值,并相应地调整文档。
如果给出且无法改变接口代码,那么我认为您可以:
- 即使您不使用参数(优选)或;
- 覆盖子类中的文档,指出您的实施不会以任何方式使用该参数,甚至不是检查。