Est-il sûr de ClassCastException de capture silencieusement lors de la recherche d'une valeur spécifique?
-
10-10-2019 - |
Question
Supposons que je suis une collection triée de mise en œuvre - Considérez ceci (incomplète) la mise en œuvre (simple exemple un Set
basé sur un tableau trié.):
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;
}
Maintenant, nous allons créer un ensemble de nombres entiers
Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);
et de test si elle contient des valeurs spécifiques:
System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));
La troisième ligne ci-dessus jeter un ClassCastException
. Pas ce que je veux. Je préférerais qu'il revienne false
(comme le fait HashSet
.)
Je peux obtenir ce comportement en attrapant l'exception soit faux:
@Override
public boolean contains(Object key) {
try {
return Arrays.binarySearch(array, key, comparator) >= 0;
} catch (ClassCastException e) {
return false;
}
}
En supposant que la collection source
est correctement typé , ce qui pourrait mal tourner si je fais ça?
La solution
Je ne pense pas qu'il y ait un problème avec ce que le Javadoc Collection.contains
indique clairement que jeter un ClassCastException
is en option.
La seule question Je vois est que si vous avez un bug quelque part ne pas jeter une exception vous évitera de le localiser.
Autres conseils
La classe TreeSet
ne jette un ClassCastException
pour les arguments incompatibles à contains()
(incompatibles pour le Comparator
utilisé par l'ensemble). Donc, il n'y a rien de mal à lancer cette exception. Assurez-vous que cela peut documentez arriver.
Il est parfaitement légitime de laisser un jet de CCE de contains (). Cependant, de nombreuses implémentations de collecte qui attrapent et faux retour, que je considère être aussi tout à fait légitime, et en fait, est le comportement plus convivial.
est égal à () vous n'avez pas le choix; vous devez attraper ce CCE.
Attraper une exception non contrôlée doit toujours se sentir sale, mais il est parfois la bonne chose à faire.