try / catch versus throws Exception

¿Son estas declaraciones de código equivalentes? ¿Hay alguna diferencia entre ellos?

private void calculateArea() throws Exception { ....do something } 

 private void calculateArea() { try { ....do something } catch (Exception e) { showException(e); } } 

Sí, hay una gran diferencia: el último se traga la excepción (mostrándola, ciertamente), mientras que el primero la dejará propagarse. (Supongo que showException no lo vuelve a lanzar).

Por lo tanto, si llama al primer método y “hacer algo” falla, la persona que llama tendrá que manejar la excepción. Si llama al segundo método y “hacer algo” falla, entonces la persona que llama no verá una excepción … lo que generalmente es algo malo, a menos que showException haya manejado la excepción, haya arreglado lo que estaba mal, y generalmente hecho Seguro que calculateArea ha logrado su propósito.

Podrás decir esto, porque no puedes llamar al primer método sin capturarte Exception o declarar que tu método también podría lanzarlo.

Sí. La versión que declara throws Exception requerirá que el código de llamada maneje la excepción, mientras que la versión que maneja explícitamente no lo hará.

es decir, simplemente:

 performCalculation(); 

vs. mover la carga de manejar la excepción a la persona que llama:

 try { performCalculation(); catch (Exception e) { // handle exception } 

El primero throws Exception , por lo que la persona que llama debe manejar la Exception . La segunda captura y maneja Exception internamente, por lo que la persona que llama no tiene que hacer ningún manejo de excepción.

Sí, hay una gran diferencia entre ellos. En el primer bloque de código, pasa la excepción al código de llamada. En el segundo bloque de código lo manejas tú mismo. El método correcto depende completamente de lo que esté haciendo. En algunos casos, desea que su código maneje la excepción (si no se encuentra un archivo y desea crearlo, por ejemplo) pero en otros, desea que el código de llamada maneje la excepción (no se encuentra un archivo). y necesitan especificar uno nuevo o crearlo).

Hablando en general también, no desea atrapar una excepción genérica. En su lugar, querrá capturar solo los específicos, como FileNotFoundException o IOException ya que pueden significar cosas diferentes.

Hay un escenario particular en el que no podemos usar throws, tenemos que usar try-catch. Existe una regla “Un método anulado no puede arrojar ninguna excepción adicional a la que está lanzando su clase principal”. Si hay alguna excepción adicional que deba manejarse con try-catch. Considere este fragmento de código. Hay una clase base simple

 package trycatchvsthrows; public class Base { public void show() { System.out.println("hello from base"); } } 

y es clase derivada:

 package trycatchvsthrows; public class Derived extends Base { @Override public void show() { // TODO Auto-generated method stub super.show(); Thread thread= new Thread(); thread.start(); try { thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } // thread.sleep(10); // here we can not use public void show() throws InterruptedException // not allowed } } 

Cuando tenemos que llamar a thread.sleep () estamos obligados a usar try-catch, aquí no podemos usar:

  public void show() throws InterruptedException 

porque el método reemplazado no puede arrojar excepciones adicionales.

Supongo que por “idéntico” te refieres al comportamiento.

El comportamiento de una función puede determinarse por:

1) valor devuelto

2) excepciones lanzadas

3) Efectos secundarios (es decir, cambios en el montón, sistema de archivos, etc.)

En este caso, el primer método propaga cualquier excepción, mientras que el segundo no arroja ninguna excepción comprobada, y se traga la mayoría de las excepciones no verificadas también, por lo que el comportamiento ES diferente.

Sin embargo, si usted garantiza que “hacer algo” nunca arroja una excepción, entonces el comportamiento sería idéntico (aunque el comstackdor requerirá que la persona que llama maneje la excepción, en la primera versión)

–editar–

Desde el punto de vista del diseño de API, los métodos son completamente diferentes en su contrato. Además, throwing class Exception no es recomendable. Intente arrojar algo más específico para permitir que la persona que llama maneje mejor la excepción.

Si lanzó una excepción, el método secundario (que anula esto) debería manejar la excepción

ejemplo:

 class A{ public void myMethod() throws Exception{ //do something } } A a=new A(); try{ a.myMethod(); }catch Exception(e){ //handle the exception } 

La persona que llama de este método deberá detectar esta excepción o declarar que se volverá a lanzar en su firma de método.

 private void calculateArea() throws Exception { // Do something } 

En el ejemplo del bloque try-catch a continuación. La persona que llama de este método no tiene que preocuparse por manejar la excepción, ya que ya se ha solucionado.

 private void calculateArea() { try { // Do something } catch (Exception e) { showException(e); } } 

Muchas veces desea que la persona que llama maneje la excepción. Supongamos que hace que la persona que llama invoque un método que llama a otro método que llama a otro método, en lugar de que cada método maneje la excepción, puede manejarlo en la persona que llama. A menos que desee hacer algo en uno de los métodos cuando ese método falla.