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

发布于 2024-10-12 01:31:02 字数 1412 浏览 6 评论 0原文

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

Suppose I am implementing a sorted collection (simple example - a Set based on a sorted array.) Consider this (incomplete) implementation:

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;

}

Now let's create a set of integers

Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);

And test whether it contains some specific values:

System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));

The third line above will throw a ClassCastException. Not what I want. I would prefer it to return false (as HashSet does.)

I can get this behaviour by catching the exception and returning false:

@Override    
public boolean contains(Object key) {
    try {
        return Arrays.binarySearch(array, key, comparator) >= 0;
    } catch (ClassCastException e) {
        return false;
    }
}

Assuming the source collection is correctly typed, what could go wrong if I do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

只怪假的太真实 2024-10-19 01:31:02

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

我看到的唯一问题是,如果某处有错误,不抛出异常将阻止您查明它。

I don't think there is any issue with this as the Javadoc for Collection.contains clearly states that throwing a ClassCastExceptionis optional.

The only issue I see is that if you have a bug somewhere not throwing an exception will prevent you to pinpoint it.

捂风挽笑 2024-10-19 01:31:02

TreeSet 类确实会因 contains() 的参数不兼容而引发 ClassCastException(与使用的 Comparator 不兼容)放)。所以抛出这个异常并没有什么问题。只要确保您记录了这种情况可能会发生即可。

The TreeSet class does throw a ClassCastException for incompatible arguments to contains() (incompatible for the Comparator used by the set). So there is nothing wrong with throwing that exception. Just make sure you document that this may happen.

遇见了你 2024-10-19 01:31:02

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

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

捕获未经检查的异常总是让人感觉很脏,但有时这是正确的做法。

It is perfectly legitimate to let a CCE throw from contains(). However, many collection implementations catch that and return false, which I consider to also be perfectly legitimate, and in fact is the more user-friendly behavior.

In equals() you don't have the choice; you have to catch that CCE.

Catching an unchecked exception should always feel dirty, but sometimes it is the right thing to do.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文