在搜索特定值时静默捕获ClassCastException是否安全?

时间:2011-01-12 22:07:41

标签: java collections exception-handling classcastexception

假设我正在实现一个有序集合(简单示例 - 基于排序数组的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集合输入正确,如果我这样做会出现什么问题?

3 个答案:

答案 0 :(得分:3)

我不认为这有任何问题,因为Collection.contains的Javadoc明确指出抛出ClassCastException是可选的。

我看到的唯一的问题是,如果你有某个某个的错误没有抛出异常会阻止你查明它。

答案 1 :(得分:1)

TreeSet类会为ClassCastException的不兼容参数抛出contains()(与集合使用的Comparator不兼容)。因此抛出异常并没有错。只需确保记录可能发生这种情况。

答案 2 :(得分:1)

让CCE从contains()中抛出是完全合法的。但是,许多集合实现捕获并返回false,我认为这也是完全合法的,事实上是更加用户友好的行为。

在equals()中你没有选择;你必须赶上那个CCE。

捕获未经检查的异常应该总是感觉很脏,但有时这是正确的。