kind - ¿Cómo manejas las excepciones "imposibles" en Java?
throw exception java (4)
A veces, terminaré teniendo que detectar una excepción que sé que nunca puede suceder, como aquí
URLDecoder.decode("some string", "UTF-8"); //No unknown encoding possible
o aquí:
public void methodWithURL(URL url){
URI uri = new URI(url); //No invalud URI syntax possible
}
Como manejas esto? Por lo general, registro un error divertido sobre cómo han cambiado las leyes del universo y luego lanzo una RuntimeException
. ¿Hay alguna manera mejor?
Aquí está mi solución: desarrollada para Android, pero se puede adaptar fácilmente para Java "regular":
public class ImpossibleException extends RuntimeException {
public ImpossibleException(@NonNull String whyNotPossible) {
this(whyNotPossible, null);
}
public ImpossibleException(@NonNull String whyNotPossible, Throwable throwable) {
super("Impossible exception: " + whyNotPossible, throwable);
Log.e("Impossible", whyNotPossible, throwable);
}
}
Uso:
try {
byte[] data = "Hello".getBytes("utf-8");
Log.i("Test", "data.length=" + data.length);
} catch (UnsupportedEncodingException e) {
throw new ImpossibleException("Android always supports utf-8", e);
}
El constructor whyNotPossible
significa que no hay necesidad de registrar el error donde ocurre, y tampoco hay necesidad de un comentario.
Supongo que es una cuestión de gusto si esto debería ser una ImpossibleException extends RuntimeException
o una ImpossibleError extends Error
.
Bueno, en mi humilde opinión, hay una mejor manera que "log [ging] un error gracioso con respecto a cómo las leyes del universo han cambiado" porque al hacerlo estás "siendo lindo", lo cual entre amigos está bien pero no es universal (no hay juego de palabras) destinado) aceptado. Los demás pueden leer tu código y si tu humor no es plano (en ellos) realmente no has hecho amigos.
Muchas guías de estilo hacen sugerencias para excepciones imposibles. Puede usar un bloque catch vacío con el parámetro de excepción que se llamará willNeverHappen
; Puedes colocar un comentario en el bloque vacío; puede lanzar una excepción de tiempo de ejecución (probablemente la mejor, ya que ¡ PODRÍA haber escrito incorrectamente UTF-8!)
Si quieres ser súper ambicioso, puedes escribir una anotación, como SneakyThrows en Lombok . Si consideras esto "mejor" es simplemente una cuestión de gustos. :)
Tenga en cuenta que esta pregunta se trató en https://softwareengineering.stackexchange.com/questions/122233/how-to-deal-with-checked-exceptions-that-cannot-ever-be-thrown .
Cojo la Exception
y la envuelvo en un Error
. desde el documento de Error
:
Un error es una subclase de Throwable que indica problemas graves que una aplicación razonable no debería intentar detectar.
Me saltearía el mensaje gracioso.
Por cierto: tuve un caso en el que un fragmento de código (en una pequeña biblioteca) simplemente asumió que habría una codificación disponible. Solo se implementó en un dispositivo limitado y explotó en tiempo de ejecución.
Las excepciones comprobadas sirven para mostrar los lugares en nuestro código donde debemos pausar por un segundo y considerar las rutas menos transitadas (como en "lo que hace mi aplicación cuando la red muere" y otros casos de esquina). Envolverlos en IllegalStateException y relanzar es una especie de contrato firmado, donde el programador dice: "sí, todos los riesgos considerados, asumo toda la responsabilidad del lugar justo aquí". Si no fuera por las excepciones verificadas, no tendríamos ninguna manera de conocer una decisión consciente por una simple falta de pensamiento.