Algunas personas intentan convencerte de que tienes que seguir las reglas. Escuche, pero si obedece, debe decidir usted mismo dependiendo de su situación. La realidad es que "DEBES jugar según las reglas" (no "DEBES seguir las reglas"). Solo tenga en cuenta que si no cumple con las reglas, puede haber consecuencias.
La situación no solo se aplica en la situación de RunnableJava 8, sino también con mucha frecuencia en el contexto de Streams y otros lugares donde se han introducido interfaces funcionales sin la posibilidad de lidiar con excepciones comprobadas. Por ejemplo, Consumer, Supplier, Function, BiFunctiony así sucesivamente todos han sido declarados sin instalaciones para lidiar con excepciones comprobadas.
Entonces, ¿cuáles son las situaciones y las opciones? En el texto siguiente, Runnablees representativo de cualquier interfaz funcional que no declara excepciones, o declara excepciones demasiado limitadas para el caso de uso en cuestión.
- Usted mismo ha declarado en
Runnablealgún lugar y podría reemplazarlo Runnablecon otra cosa.
- Considere reemplazar
Runnablecon Callable<Void>. Básicamente lo mismo, pero permite lanzar excepciones; y tiene que hacerlo return nullal final, lo cual es una leve molestia.
- Considere reemplazar
Runnablecon su propia costumbre @FunctionalInterfaceque puede lanzar exactamente las excepciones que desee.
- Ha utilizado una API y hay alternativas disponibles. Por ejemplo, algunas API de Java están sobrecargadas, por lo que podría usar en
Callable<Void>lugar de Runnable.
- Ha utilizado una API y no hay alternativas. En ese caso, todavía no te quedan opciones.
- Puede envolver la excepción en
RuntimeException.
- Puede piratear la excepción en una RuntimeException utilizando una conversión sin marcar.
Puedes probar lo siguiente. Es un truco, pero a veces lo que necesitamos es un truco. Porque, si una excepción debe estar marcada o desmarcada se define por su tipo, pero prácticamente debería estar definida por la situación.
@FunctionalInterface
public interface ThrowingRunnable extends Runnable {
@Override
default void run() {
try {
tryRun();
} catch (final Throwable t) {
throwUnchecked(t);
}
}
private static <E extends RuntimeException> void throwUnchecked(Throwable t) {
throw (E) t;
}
void tryRun() throws Throwable;
}
Prefiero esto new RuntimeException(t)porque tiene un seguimiento de pila más corto.
Ahora puedes hacer:
executorService.submit((ThrowingRunnable) () -> {throw new Exception()});
Descargo de responsabilidad: la capacidad de realizar conversiones no verificadas de esta manera podría eliminarse en versiones futuras de Java, cuando la información de tipo genérico se procesa no solo en tiempo de compilación, sino también en tiempo de ejecución.