Безопасно ли молча перехватывать ClassCastException при поиске определенного значения? - PullRequest
4 голосов
/ 13 января 2011

Предположим, я реализую отсортированную коллекцию (простой пример - 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 ]

3 голосов
/ 13 января 2011

Я не думаю, что есть какая-либо проблема с этим, поскольку Javadoc для Collection.contains ясно заявляет, что бросать ClassCastException необязательно.

Единственная проблема Я вижу, что если у вас есть ошибка где-то , исключение исключения не позволит вам точно его определить.

1 голос
/ 19 января 2011

Вполне допустимо, чтобы CCE сгенерировал метод contains ().Однако многие реализации коллекций ловят это и возвращают false, что я считаю также вполне законным, и на самом деле это более удобное для пользователя поведение.

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

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

1 голос
/ 13 января 2011

Класс TreeSet выдает ClassCastException для несовместимых аргументов в contains() (несовместимо для Comparator, используемого набором). Так что в этом исключении нет ничего плохого. Просто убедитесь, что вы задокументировали, что это может произойти.

...