在搜索特定值时,默默地捕获ClassCastException是否安全?
-
10-10-2019 - |
题
假设我正在实现一个分类集合(简单示例 - a 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
做。)
我可以通过捕获异常并返回错误来获得这种行为:
@Override
public boolean contains(Object key) {
try {
return Arrays.binarySearch(array, key, comparator) >= 0;
} catch (ClassCastException e) {
return false;
}
}
假设 source
收集正确键入, ,如果我这样做会怎么办?
解决方案
我认为这没有任何问题作为Javadoc Collection.contains
显然指出扔 ClassCastException
是可选的。
唯一的 问题 我知道是如果您有错误 某处 不抛出例外会阻止您确定它。
其他提示
这 TreeSet
班级确实扔了 ClassCastException
对于不兼容的论点 contains()
(不兼容 Comparator
该集合使用)。因此,抛出该例外没有错。只需确保您记录这可能会发生。
让CCE从contains()扔掉是完全合法的。但是,许多收集实现都会抓住并返回错误,我认为这也是完全合法的,实际上是更友好的行为。
在equals()中,您没有选择;您必须抓住该CCE。
抓住不受限制的例外应该总是感到肮脏,但有时候这是正确的事情。
不隶属于 StackOverflow