Безопасно ли молча поймать ClasscastException при поиске определенного значения?

StackOverflow https://stackoverflow.com/questions/4674553

Вопрос

Предположим, я внедряю сортированную коллекцию (простой пример - 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 бросить из Sontains (). Тем не менее, многие реализации коллекции поймают это и возвращают ложные, которые я считаю совершенно законным, и на самом деле является более удобным поведением.

В equals () у вас нет выбора; Вы должны поймать эту CCE.

Поймать неконтролируемое исключение всегда должно чувствовать себя грязно, но иногда это правильно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top