4 votes

Est-il possible d'attraper silencieusement une ClassCastException lors de la recherche d'une valeur spécifique ?

Supposons que je mette en œuvre une collection triée (exemple simple - une Set sur la base d'un tableau trié). Considérez cette implémentation (incomplète) :

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;

}

Créons maintenant un ensemble d'entiers

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

Et vérifiez s'il contient certaines 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 lancera un ClassCastException . Ce n'est pas ce que je veux. Je préférerais qu'il revienne false (comme HashSet fait.)

Je peux obtenir ce comportement en capturant l'exception et en renvoyant false :

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

En supposant que le source la collection est correctement typée qu'est-ce qui pourrait mal se passer si je fais ça ?

3voto

gabuzo Points 3181

Je ne pense pas qu'il y ait de problème à ce sujet, car la Javadoc de l'application Collection.contains indique clairement que le fait de lancer un ClassCastException est facultatif.

Le seul numéro Je vois que si vous avez un bug quelque part ne pas lancer d'exception vous empêchera de la localiser.

1voto

Christian Semrau Points 4467

El TreeSet lance un ClassCastException pour des arguments incompatibles avec contains() (incompatible avec le Comparator utilisé par l'ensemble). Il n'y a donc rien de mal à lancer cette exception. Assurez-vous simplement de documenter le fait que cela peut arriver.

1voto

Kevin Bourrillion Points 19677

Il est parfaitement légitime de laisser un CCE lancer de contains(). Cependant, beaucoup d'implémentations de collections attrapent cela et renvoient false, ce que je considère également comme parfaitement légitime, et qui est en fait le comportement le plus convivial.

Dans equals(), vous n'avez pas le choix ; vous devez attraper ce CCE.

Le fait d'attraper une exception non vérifiée devrait toujours être mal perçu, mais c'est parfois la bonne chose à faire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X