todas tipos que propia personalizadas las lanzar excepción excepciones ejemplos crear clase capturar java exception checked-exceptions

que - tipos de excepciones en java



¿Cómo lanzar una excepción cuando la firma de su método no permite lanzar una excepción? (3)

Tengo un método como este:

public void getSomething(){ ... }

Quiero lanzar una Exception dentro de getSomething() . El compilador no me permitirá hacerlo porque mi método no permite que se lance Exception allí. Pero necesito lanzar una subclase de Exception para mis pruebas (no puedo lanzar Exception no verificada ) . Esto es claramente un truco pero lo necesito para mis pruebas. Intenté con EasyMock pero tampoco me permite hacer eso. ¿Alguna idea de cómo hacer eso?

Gracias, Sean Nguyen


Java tiene dos tipos de excepciones, marcadas y sin marcar. Debe declarar las excepciones marcadas, pero no tiene que declarar las excepciones no marcadas.

RuntimeException excepción RuntimeException es la excepción básica sin marcar, por lo que puede lanzarla sin declararla.

public void getSomething(){ throw new RuntimeException("I don''t have to be declared in the method header!"); }

Como nota al margen, es probable que no desee lanzar una RuntimeException en bruto, sino una subclase de algo más específico a sus necesidades. También se desactivará cualquier subclase de RuntimeException.


No sé lo que estabas tratando de hacer. Puede simplemente lanzar una excepción no verificada dentro de su método y luego probar usando JUnit como en mi ejemplo a continuación.

public void getSomething() { throw new RuntimeException(); }

Ejemplo de prueba de JUnit 4:

@Test public void testGetSomething() { try { getSomething(); fail("Expecting RuntimeException!"); } catch (Exception e) { Logger.getLogger("test").info("Exception was caught: " + e.getClass()); } }


Método 1:

Esta publicación de Alexey Ragozin describe cómo usar un truco de genéricos para lanzar una excepción comprobada no declarada. De ese post:

public class AnyThrow { public static void throwUnchecked(Throwable e) { AnyThrow.<RuntimeException>throwAny(e); } @SuppressWarnings("unchecked") private static <E extends Throwable> void throwAny(Throwable e) throws E { throw (E)e; } }

El truco se basa en throwUnchecked "mintiendo" al compilador de que el tipo E es RuntimeException con su llamada a throwAny . Dado que throwAny se declara como throws E , el compilador piensa que esa llamada en particular puede simplemente lanzar RuntimeException . Por supuesto, el truco es posible mediante el throwAny de throwAny que E declare arbitrariamente E y ciegamente a él, lo que permite a la persona que llama decidir cuál es su argumento: un diseño terrible cuando se codifica correctamente. En el tiempo de ejecución, E se erased y no tiene ningún significado.

Como notaste, hacer tal cosa es un gran hack y deberías documentar su uso muy bien.

Método 2:

También puede utilizar sun.misc.Unsafe para este fin. Primero debes implementar un método que use la reflexión para devolver la instancia de esa clase:

private static Unsafe getUnsafe() { try { Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe"); theUnsafeField.setAccessible(true); return (Unsafe)theUnsafeField.get(null); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } }

Esto es necesario, ya que llamar a Unsafe.getUnsafe() normalmente arrojará una Unsafe.getUnsafe() SecurityException . Una vez que tenga la instancia de Unsafe , puede utilizar sus capacidades terroríficas:

Unsafe unsafe = getUnsafe(); unsafe.throwException(new Exception());

El crédito va a esta respuesta en la publicación https://.com/questions/5574241/interesting-uses-of-sun-misc-unsafe . Pensé que mencionaría esto para completar, pero probablemente sea mejor usar el truco anterior en lugar de permitir el uso de Unsafe en su código.

Método 3:

En los comentarios de la respuesta vinculada sobre el uso de Unsafe , @bestsss señala un truco mucho más simple utilizando el método obsoleto Thread.stop(Throwable) :

Thread.currentThread().stop(new Exception());

En este caso, usted usaría @SuppressWarnings("deprecation") y una vez más documentaría muy ferozmente. Una vez más, prefiero el primer truco para su limpieza (relativa).