2010-09-30 15 views
6

La respuesta directa se debe a que la interfaz de Comparator.compare se especifica de tal manera que no arroja excepciones. Pero ¿por qué es eso?Java: ¿por qué no puedo lanzar una excepción en Comparator?

O para decirlo de otra manera: Mi Comparator debe depender de una función que pueda arrojar una excepción. En teoría, eso no debería suceder. Pero si sucede, quiero que rompa toda la función donde estoy usando ese Comparator (en Collections.sort). Es decir. Quiero que simplemente se comporte como si se hubiera producido una excepción no controlada.

Parece que esto no es posible de forma natural (porque si la interfaz dice que no puede lanzar una excepción, no puede).

¿Cómo puedo solucionar esto? ¿Con un feo try/catch e imprimo la excepción y espero que la reconozca? Esa parece ser una manera bastante fea.

+2

¿Ha considerado lanzar una RuntimeException en su lugar? (posiblemente ajustando la excepción marcada) –

Respuesta

5

En este caso, volvería a generar un AssertionError ya que supone que no se puede hacer la excepción. No se olvide de utilizar el método initCause() para propagar la información (AssertionError no tiene un constructor de aceptar una Throwable)

+2

'AssertionError' tiene un constructor que acepta un' Objeto', que se usará como la causa si es 'Throwable'. (Nota al azar: creo que están mejorando esto en JDK7.) – ColinD

+0

@ColinD Wow ... Acabo de enterarme de algo. Gracias. – gawi

13

Siempre puede arrojar un RuntimeException, o uno derivado de él, incluso desde un método que no se declara explícitamente lanzar excepciones.

3

Este es el contrato del método Comparator.compare. Si desea usarlo, debe seguir la regla de no arrojar excepciones marcadas desde él :) Mientras tanto, puede lanzar una excepción sin marcar (RuntimeException o su subclase) y esto no interrumpirá el contrato.

0

Hay 2 maneras de resolver este:

  1. agarrar la excepción y arrojándolo dentro de un java.lang.RuntimeException() o
  2. La captura la excepción y madereras usando Log4J o SLF4J (o cualquier fábrica registrador de que se sienta cómodo con).

El contrato para el método de comparación del comparador no arroja excepciones.

+2

Aconsejaría no registrar el error y continuar. Este no es el tipo de error que debes ignorar. – gawi

+0

Estoy de acuerdo con usted, pero solo está haciendo una comparación, por lo tanto, en esencia, el método de comparación supone que no se deben lanzar excepciones. Además, al registrar la excepción, tiene un stacktrace en el archivo para mostrar dónde se produjo la excepción. –

+0

El método de registro le indicará dónde se produjo la primera de sus excepciones, ya que es muy probable que se generen más excepciones cuando se ignoran las excepciones (y sí, inicie sesión y siga trabajando = ignorando). – whiskeysierra

1

le preguntas a diferentes preguntas en el título de la pregunta y la pregunta en el cuerpo.

No tenía claro por qué la función con capacidad de excepción utilizada por el método compare() lanzaría una excepción. O bien porque hay ciertos objetos no comparables en la colección (como un valor numérico NaN) o sino porque hay ciertos pares de objetos que no se pueden comparar entre sí.

¿Por qué no puedo lanzar una excepción en el Comparador?

Conjeturaría Comparator.compare() no está diseñado para lanzar una excepción comprobada porque:

  1. se supone que todos los elementos que usted desea comparar/especie siempre serían comparables.

  2. si un Comparator.compare() podría arrojar algún tipo de esperado (es decirverificado), entonces puedo imaginar un par de escenarios no deseados:

    a. un género podría abortar porque hay algún tipo de objeto incomparable, la respuesta probable es eliminar los objetos no comparables y probar el género nuevamente

    b. varias ordenaciones en los diferentes ordenamientos de la misma colección de objetos a veces puede abortar con una excepción y, a veces tener éxito en función de si o no un par de objetos incomparables pasó a venir para la comparación durante la ordenación

Esto es, por supuesto, solo mi conjetura

¿Cómo puedo solucionar esto?

que va a suponer que la razón por la función de excepciones posible que utiliza su Comparator.compare() lanza una excepción se debe a que hay un objeto incomparable en la colección (como un valor Numberic NaN). Las opciones incluyen:

  1. Ordenar una copia de la lista con el objeto uncomparable (s) eliminado.

  2. Lanza una excepción no verificada (en tiempo de ejecución) para cancelar el ordenamiento. No estoy seguro de lo que haría entonces que no sea el # 1 anterior.

  3. Sigue el enfoque NaN y haz que los objetos salgan al principio o al final.

    NaN los valores normalmente no se pueden comparar con otros valores, pero durante una ordenación, el comparador define su propio orden total para que los valores NaN terminen al final de la colección ordenada.

    http://download.oracle.com/javase/1.4.2/docs/api/java/util/Arrays.html#sort (double [])

    ... La relación < no proporciona un orden total en todos los valores de coma flotante; ... un valor de NaN no compara ni menos que, ni más ni menos que ningún valor de coma flotante, incluso a sí mismo.

    ... Para permitir que la clasificación continúe, ... este método usa el orden total impuesto por Double.compareTo (java.lang.Double).

    ... Este orden difiere de la relación < en que ... NaN se considera mayor que cualquier otro valor de coma flotante. A los efectos de la clasificación, todos los valores de NaN se consideran equivalentes e iguales.

    Para hacer esto, el código de su Comparator.compare() de tal manera que cualquier objeto incomparable compara siempre mayor que cualquier objeto comparable y se compara siempre igual a cualquier otro objeto incomparable.

0

Puede volver a lanzar una excepción comprobada y evitar el error de compilación mediante el uso de una serie de trucos. El más simple es;

try { 
    // something 
} catch (Exception e) { 
    Thread.currentThread().stop(e); 
} 

Sin embargo, como el compilador no tiene idea de que ha hecho esto. Puedes confundirlo y a ti mismo si no tienes cuidado. Uno de los objetivos de los cierres es manejar las excepciones comprobadas en cosas como los Comparadores correctamente (mientras que otros preferirían que se fueran)

Cuestiones relacionadas