usuario una try relanzar por new lanza funciona excepciones excepcion ejemplos definidas declaracion como catch java

java - una - throws exception ejemplos



Retirar una excepción: ¿por qué compila el método sin una cláusula throws? (6)

En el código fuente a continuación, estoy volviendo a lanzar una Exception .
¿Por qué no es necesario poner la palabra clave throws en la firma del método?

public void throwsOrNotThrowsThatsTheQuestion() { try { // Any processing } catch (Exception e) { throw e; } }


¿Por qué no es necesario poner la palabra clave throws en la firma del método?

Puedes poner eso como causa // Any processing no arroja ninguna excepción marcada .

Ejemplo:

Esto compila bien.

public void throwsOrNotThrowsThatsTheQuestion() { try { throw new RuntimeException(); } catch (Exception e) { throw e; }

Esto no se compilará, debe agregar la cláusula throws .

public void throwsOrNotThrowsThatsTheQuestion() { try { throw new Exception(); } catch (Exception e) { //do something like log and rethrow throw e; } }

Esto funciona desde Java 7. En la versión anterior, se lanza una excepción. Más información de nuevo en java 7


lanzar nueva Exception(); es algo que nunca deberías hacer en un bloque de catch, pero es posible que tengas que hacerlo o quieras throw new SomeException(throwable); (preservando el rastro completo de la pila) en lugar de throw throwable; para ajustarse a la API de su método, por ejemplo, cuando declara lanzar SomeException pero está llamando al código que podría lanzar una IOException que no desea agregar a la cláusula throws de su método.

El caso probablemente más común es la nueva RuntimeException (throwable); para evitar tener una cláusula throws por completo.


Cuando utiliza throws con un método, significa que la instrucción que llamará a ese método debe estar rodeada por un bloque try catch.

Pero si el método ya incluye try catch block, entonces no se necesita ninguna declaración de thorws ya que la excepción que arroja el método se está manejando solo allí.

La instrucción que llama a este método no necesita estar rodeada de try catch block.

Espero que esto aclare tu duda.


Este comportamiento parece ocurrir solo en Java 1.7. Al compilar con 1.6, recibo el siguiente mensaje de error del compilador:

c:/dev/src/misc>javac -source 1.6 Main.java warning: [options] bootstrap class path not set in conjunction with -source 1.6 Main.java:22: error: unreported exception Exception; must be caught or declared to be thrown throw e; ^ 1 error 1 warning

Pero con Java 1.7, compila.

c:/dev/src/misc>javac -source 1.7 Main.java c:/dev/src/misc>

... Hasta que lanzo una Exception en el bloque try :

public static void throwsOrNotThrowsThatsTheQuestion() { try { // Any processing throw new IOException("Fake!"); } catch (Exception e) { throw e; }

Compilando ...

c:/dev/src/misc>javac -source 1.7 Main.java Main.java:22: error: unreported exception IOException; must be caught or declare d to be thrown throw e; ^ 1 error

Parece que Java 1.7 fue lo suficientemente inteligente como para detectar el tipo de Exception (s) que podría arrojarse al analizar el código try block, donde como 1.6 acaba de ver throw e; de tipo Exception y dio un error solo por eso.

Al cambiarlo para lanzar una RuntimeException se compiló como se esperaba, porque, como siempre, las Exception no verificadas no necesitan una cláusula throws :

public static void throwsOrNotThrowsThatsTheQuestion() { try { // Any processing throw new RuntimeException("Fake!"); } catch (Exception e) { throw e; }

Compilando ...

c:/dev/src/misc>javac -source 1.7 Main.java c:/dev/src/misc>

La explicación

Esto es lo que está pasando:

Java 7 introdujo una comprobación de tipo más inclusiva . Citando ...

Considere el siguiente ejemplo:

static class FirstException extends Exception { } static class SecondException extends Exception { } public void rethrowException(String exceptionName) throws Exception { try { if (exceptionName.equals("First")) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } }

El bloque try de este ejemplo podría lanzar FirstException o SecondException. Supongamos que desea especificar estos tipos de excepción en la cláusula throws de la declaración del método rethrowException. En versiones anteriores a Java SE 7, no puede hacerlo. Como el parámetro de excepción de la cláusula catch, e, es type Exception, y el bloque catch vuelve a lanzar el parámetro de excepción e, solo puede especificar el tipo de excepción Exception en la cláusula throws de la declaración del método rethrowException.

Sin embargo, en Java SE 7, puede especificar los tipos de excepción FirstException y SecondException en la cláusula throws en la declaración del método rethrowException . El compilador de Java SE 7 puede determinar que la excepción lanzada por la instrucción throw e debe provenir del bloque try, y que las únicas excepciones lanzadas por el bloque try pueden ser FirstException y SecondException. Aunque el parámetro de excepción de la cláusula catch, e, es type Exception, el compilador puede determinar que es una instancia de FirstException o SecondException:

(énfasis mío)

public void rethrowException(String exceptionName) throws FirstException, SecondException { try { // ... } catch (Exception e) { throw e; } }


Si busca una excepción marcada, debe tenerla en la lista de tiradas

public void retrhowChecked() throws Exception { try { throw new IOException(); } catch(Exception e) { throw e; } }

Si lanza una excepción sin marcar no necesita ponerla en la lista de lanzamientos, puede usar esto para empaquetar una Excepción marcada dentro de una casilla no marcada para evitar romper el código que usa este método si cambia el método en cuestión en tal forma en que después del cambio puede producir una excepción marcada. Pero tienes que tener cuidado con eso, la Excepción comprobada está ahí para ser manejada.

public void retrhowUnchecked() { try { throw new IOException(); } catch(Exception e) { throw new RuntimeException(e); } }

Lea más sobre Excepciones here .


java.lang.Exception es una excepción comprobada por lo que no funcionará o incluso compilará. Funcionaría con un código incrustado (java.lang.RuntimeException). Absolutamente no hay diferencia si arrojas una excepción dentro de un bloque catch o no.

El error del compilador sería algo como esto (dependiendo del compilador):

java: excepción no reportada java.lang.Exception; debe ser atrapado o declarado arrojado

EDITAR: Java 7 puede manejar tales situaciones si nunca lanzas la excepción