gpt4 book ai didi

Java 7 更改了 Collections.checkedCollection 的行为以允许 null。 API 在混合环境中使用它是否仍然值得?

转载 作者:太空宇宙 更新时间:2023-11-04 08:05:31 24 4
gpt4 key购买 nike

首先,这是 Java 7's Collections.checked* 添加的行为:

Since null is considered to be a value of any reference type, the returned collection permits insertion of null elements whenever the backing collection does.

这似乎没有列在 compatibility documentation 中, 尽管。演示:

public class MyAPI {
private Set<Polygon> polygons = new Collections.checkedSet(new HashSet<Polygon>(), Polygon.class);
public Set<Polygon> getPolygons() {
return polygons;
}
}
public class MyAPITest {
// This JUnit test passes when using Java 6 or earlier, but fails for Java 7.
@Test(expected=NullPointerException.class)
public void testAddNullPolygon() {
new MyAPI().getPolygons().add(null);
}
}

正如您所看到的,我正在编写一个 API,它公开一个 Set 供客户端代码填充。据我所知,这是 Collections.checkedCollection 等的用例之一:添加的运行时检查有助于防止插入奇怪的东西。

无论如何,我已经更改了 API 来处理 null,但我担心客户端代码有时会抛出 NPE,有时不会,具体取决于最终用户运行的 Java 版本。就是感觉很 splinter 。理想情况下,我想保留旧的行为,防止插入时出现空值。

我想我的选择是:

  1. 完全放弃运行时检查。

  2. 不用担心,并相信客户端代码永远不会插入空值。

  3. 声明我的 API 仅支持 JRE 7。

  4. 使用 Guava,它看起来很棒,但它是我的 API 需要承担的额外依赖项。

  5. 推出我自己的 Set 包装器,强制执行 null 和类型检查。

  6. 我缺少的一些其他更优雅的解决方案。

任何指导将不胜感激!

最佳答案

我最终选择的选项是删除checkedCollection,使公开的集合不可修改。 API 的用户需要调用额外的添加/删除/清除方法之一来修改集合。

这在一定程度上限制了 API 用户:例如,他们无法在单个方法调用中使用 addAll 复制另一个集合的所有元素。但这是简单性和类型安全性之间的公平权衡。

public class MyAPI {
private Set<Polygon> polygons = new HashSet<Polygon>();
private Set<Polygon> polygonsReadonlyView = Collections.unmodifiableSet(polygons);
public Set<Polygon> getPolygons() {
return polygonsReadonlyView;
}
public boolean addPolygon(Polygon p) {
if (p == null) {
throw new IllegalArgumentException("polygon cannot be null");
}
return polygons.add(p);
}
public boolean removePolygon(Polygon p) {
return polygons.remove(p);
}
public void clearPolygons() {
polygons.clear();
}
}

所有这一切的一个要点是永远不要依赖checkedCollection来防止插入空值。

Google 搜索可能会建议这样做...但不要这样做!空检查不是checkedCollection 的用例之一。

关于Java 7 更改了 Collections.checkedCollection 的行为以允许 null。 API 在混合环境中使用它是否仍然值得?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12147898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com