我有一个给出Set
个对象的方法。它委派的方法要求Set
不包含任何null元素。我希望check the precondition Set
在委托之前的方法中尽早包含空元素。明显的代码是这样做的:
public void scan(Set<PlugIn> plugIns) {
if (plugIns == null) {
throw new NullPointerException("plugIns");
} else if (plugIns.contains(null)) {
throw new NullPointerException("plugIns null element");
}
// Body
}
但这是不正确的,因为如果NullPointerException
实现本身不允许空元素,Set.contains()
可能会抛出Set
。在这种情况下捕获然后忽略NullPointerException
将起作用but would be inelegant。有没有一种巧妙的方法可以检查这个前提条件?
Set
界面是否存在设计缺陷?如果Set
实现可能永远不会包含null,那么为什么不要求Set.contains(null)
始终返回false
?或者有一个isNullElementPermitted()
谓词?
答案 0 :(得分:4)
最简单的方法是枚举Set并检查空值。
public void scan(Set<PlugIn> plugIns) {
if (plugIns == null) throw new NullPointerException("plugIns");
for (PlugIn plugIn : plugIns) {
if (plugIn == null) throw new NullPointerException("plugIns null element");
}
}
答案 1 :(得分:3)
从HashSet
创建plugIns
并检查是否存在null
public void scan(Set<PlugIn> plugIns) {
if (plugIns == null) throw new NullPointerException("plugIns");
Set<PlugIn> copy = new HashSet<PlugIn>(plugIns);
if (copy.contains(null)) {
throw new NullPointerException("null is not a valid plugin");
}
}
答案 2 :(得分:2)
如果抛出则捕获NullPointerException并忽略它:
public void scan(Set<PlugIn> plugIns) {
if (plugIns == null) {
throw new NullPointerException("plugIns");
}
NullPointerException e = null;
try {
if (plugIns.contains(null)) {
// If thrown here, the catch would catch this NPE, so just create it
e = new NullPointerException("plugIns null element");
}
} catch (NullPointerException ignore) { }
if (e != null) {
throw e;
}
// Body
}
这会在抛出时产生很小的开销,但是如果你不使用异常(尤其是strack跟踪),它实际上非常轻量级。