假设我正在实现一个有序集合(简单示例 - 基于排序数组的Set
。)考虑这个(不完整)实现:
import java.util.*;
public class SortedArraySet<E> extends AbstractSet<E> {
@SuppressWarnings("unchecked")
public SortedArraySet(Collection<E> source, Comparator<E> comparator) {
this.comparator = (Comparator<Object>) comparator;
this.array = source.toArray();
Arrays.sort(this.array, this.comparator);
}
@Override
public boolean contains(Object key) {
return Arrays.binarySearch(array, key, comparator) >= 0;
}
private final Object[] array;
private final Comparator<Object> comparator;
}
现在让我们创建一组整数
Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);
并测试它是否包含一些特定值:
System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));
上面的第三行将抛出ClassCastException
。不是我想要的。我希望它返回false
(如HashSet
那样。)
我可以通过捕获异常并返回false来获得此行为:
@Override
public boolean contains(Object key) {
try {
return Arrays.binarySearch(array, key, comparator) >= 0;
} catch (ClassCastException e) {
return false;
}
}
假设source
集合输入正确,如果我这样做会出现什么问题?
答案 0 :(得分:3)
我不认为这有任何问题,因为Collection.contains
的Javadoc明确指出抛出ClassCastException
是可选的。
我看到的唯一的问题是,如果你有某个某个的错误没有抛出异常会阻止你查明它。
答案 1 :(得分:1)
TreeSet
类会为ClassCastException
的不兼容参数抛出contains()
(与集合使用的Comparator
不兼容)。因此抛出异常并没有错。只需确保记录可能发生这种情况。
答案 2 :(得分:1)
让CCE从contains()中抛出是完全合法的。但是,许多集合实现捕获并返回false,我认为这也是完全合法的,事实上是更加用户友好的行为。
在equals()中你没有选择;你必须赶上那个CCE。
捕获未经检查的异常应该总是感觉很脏,但有时这是正确的。