2012-06-08 12 views
8

Teniendo en cuenta que, básicamente, quiero eliminar el uso de excepción comprobada y transformarlos tiempos de ejecución excepciones, que normalmente estaría haciendo algo como esto:¿Reemplazar una excepción marcada con una excepción de tiempo de ejecución?

try { 
    file.read(); 
} catch (IOException e){ 
    throw new RuntimeException(e); 
} 

Hay varias desventajas a hacer esto, pero el que me la irrita la mayoría es que mi excepción de tiempo de ejecución contendría una stacktrace anidada. Básicamente me gustaría volver a lanzar la "IOException" como una RuntimeException (o "IORuntimeException") con el mensaje original y stacktrace, por lo que puedo evitar el inútil stack-stack anidado. El "hecho" de que he vuelto a lanzar la excepción en algún lugar en el medio me parece un ruido inútil.

¿Esto es posible? ¿Hay alguna biblioteca que hace esto?

+0

¿Es [este] (http://robaustin.wikidot.com/rethrow-exceptions) útil? –

+2

Si le molestan las stacktraces anidadas, odiará la mayoría de los marcos y bibliotecas, que tienden a usarlos extensivamente. Me acostumbraría a eso si fuera tú. – artbristol

+0

@KazekageGaara, buena persona. Yo habría votado que si lo publicas como respuesta. – missingfaktor

Respuesta

4

Project Lombok le permite desactivar excepciones marcadas por completo.

+2

Lo suficiente, pero es demasiado complicado para mí. Prefiero simplemente hacerlo yo mismo en algún lugar – krosenvold

+3

. Dudo si hay una solución no-hacky para el problema que estás tratando de resolver. – missingfaktor

3
class IORuntimeException extends RuntimeException { 

    final IOException ioex; 

    public IORuntimeException(IOException ioex) { 
     this.ioex = ioex; 
    } 

    @Override 
    public String getMessage() { 
     return ioex.getMessage(); 
    } 

    @Override 
    public StackTraceElement[] getStackTrace() { 
     return ioex.getStackTrace(); 
    } 

    //@Override 
    // ... 
} 

(clase completa disponible here, tal como se produce por Eclipse "Generar métodos de delegado" macro.)

Uso:

try { 
    ... 
} catch (IOException ioex) { 
    throw new IORuntimeException(ioex); 
} 
+0

El problema con este enfoque es que no se puede generalizar para ningún tipo de 'Excepción', y por lo tanto causa demasiada repetición repetitiva y de código. – missingfaktor

+0

Bueno, siempre puedes hacer [esto] (http://ideone.com/9OOwd). – aioobe

+0

Sí, pero la información del tipo se pierde. Solo si Java hubiera reificado genéricos ... entonces podríamos haberlo hecho con genéricos. – missingfaktor

3

Seguimiento de mi comentario. Aquí hay un article que tiene que arrojar algo de luz sobre el tema. Utiliza sun.misc.Unsafe para volver a lanzar excepciones sin envolverlas.

2

Si está considerando el uso de la otra respuesta de condiciones de riesgo (que no recomiendo, pero de todos modos), otra opción es para abusar de los medicamentos genéricos para lanzar una excepción comprobada con este par el mal de métodos (de http://james-iry.blogspot.co.uk/2010/08/on-removing-java-checked-exceptions-by.html):

@SuppressWarnings("unchecked") 
    private static <T extends Throwable, A> 
    A pervertException(Throwable x) throws T { 
     throw (T) x; 
    } 


    public static <A> A chuck(Throwable t) { 
     return Unchecked. 
     <RuntimeException, A>pervertException(t); 
    } 

También puede consultar com.google.common.base.Throwables.getRootCause(Throwable) y simplemente imprimir su rastro de pila (raíz).

0

suena como que realmente necesitan las excepciones comprobadas

0

A partir de Java 8 hay otra manera:

try { 
    // some code that can throw both checked and runtime exception 
} catch (Exception e) { 
    throw rethrow(e); 
} 

@SuppressWarnings("unchecked") 
public static <T extends Throwable> RuntimeException rethrow(Throwable throwable) throws T { 
    throw (T) throwable; // rely on vacuous cast 
} 

* Más información here.

Cuestiones relacionadas