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 quierasthrow new SomeException(throwable);
(preservando el rastro completo de la pila) en lugar de throwthrowable;
para ajustarse a la API de su método, por ejemplo, cuando declara lanzarSomeException
pero está llamando al código que podría lanzar unaIOException
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