¿Es seguro ClassCastException captura en silencio en la búsqueda de un valor específico?
-
10-10-2019 - |
Pregunta
Supongamos que yo estoy poniendo en práctica una colección ordenada - Considere esta implementación (incompleto) (un ejemplo sencillo Set
basado en un arreglo ordenado.):
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;
}
Ahora vamos a crear un conjunto de números enteros
Set<Integer> s = new SortedArraySet<Integer>(Arrays.asList(1, 2, 3), null);
Y prueba si contiene algunos valores específicos:
System.out.println(s.contains(2));
System.out.println(s.contains(42));
System.out.println(s.contains("42"));
La tercera línea anterior arrojará un ClassCastException
. No es lo que quiero. Yo preferiría que vuelva false
(como HashSet
hace.)
que puedo conseguir este comportamiento por la captura de excepción y devolver false:
@Override
public boolean contains(Object key) {
try {
return Arrays.binarySearch(array, key, comparator) >= 0;
} catch (ClassCastException e) {
return false;
}
}
Suponiendo que la colección source
está correctamente escrita a máquina , lo que podría ir mal si hago esto?
Solución
No creo que hay algún problema con esto como el Javadoc para Collection.contains
establece claramente que lanzar un ClassCastException
is opcional.
El único tema que veo es que si usted tiene un error alguna parte no lanzar una excepción evitará que para localizar a él.
Otros consejos
La clase TreeSet
hace lanzar una ClassCastException
de argumentos incompatibles a contains()
(incompatibles para la Comparator
utilizado por el conjunto). Así que no hay nada de malo en que lanzar una excepción. Sólo asegúrese de documentar que esto puede suceder.
Es perfectamente legítimo para que un tiro de CCE contains (). Sin embargo, muchas implementaciones de recogida de captura que falsa y de retorno, que considero también ser perfectamente legítima, y ??de hecho es el comportamiento más fácil de usar.
En equals () no tiene la elección; usted tiene que coger ese CCE.
La captura de una excepción sin control siempre debe sentirse sucio, pero a veces es lo que hay que hacer.