2010-12-08 12 views
73

Así que pensé que tenía una buena comprensión básica del manejo de excepciones en Java, pero hace poco estuve leyendo un código que me dio cierta confusión y dudas. Mi duda principal que quiero tratar aquí es cuando se debe utilizar un observador lanza en una declaración de método Java como la siguiente:Cuándo utilizar throws en una declaración de método Java?

public void method() throws SomeException 
    { 
     // method body here 
    } 

De la lectura de algunos mensajes similares deduzco que tiros se utiliza como una especie de declaración que SomeException podría lanzarse durante la ejecución del método.

Mi confusión proviene de un código que se veía así:

 public void method() throws IOException 
    { 
      try 
      { 
       BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
      } 
      catch(IOException e) 
      { 
       System.out.println(e.getMessage()); 
      } 
    }

¿Hay alguna razón por la que se desea utilizar un tiros en este ejemplo? Parece que si solo está haciendo un manejo básico de excepciones de algo así como una IOException, simplemente necesitaría el bloque try/catch y eso es todo.

Respuesta

71

Si está buscando un tipo de excepción, no necesita tirarlo, a menos que vaya a volver a lanzarlo. En el ejemplo que publica, el desarrollador debería haber hecho uno u otro, no ambos.

Normalmente, si no va a hacer nada con la excepción, no debería atraparlo.

Lo más peligroso que puede hacer es atrapar una excepción y no hacer nada con ella.

Una buena discusión de cuándo es apropiado para lanzar excepciones es aquí

When to throw an exception?

+1

En caso de que las excepciones sin marcar también se declaren en la firma del método con un 'throws', ¿o es práctica usar solo 'throws' para las excepciones marcadas? – Cody

2

Tiene razón, en ese ejemplo el throws es superfluo. Es posible que se haya dejado allí debido a alguna implementación previa, tal vez la excepción se lanzó originalmente en lugar de quedar atrapada en el bloque catch.

1

En el ejemplo que proporcionó, el método nunca lanzará una IOException, por lo tanto, la declaración es incorrecta (pero válida). Supongo que el método original arrojó IOException, pero luego se actualizó para manejar la excepción dentro pero la declaración no se modificó.

18

Solo necesita incluir una cláusula throws en un método si el método arroja una excepción marcada. Si el método arroja una excepción de tiempo de ejecución, entonces no hay necesidad de hacerlo.

Vea aquí algunos antecedentes sobre comprobó vs excepciones sin marcar: http://download.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Si el método detecta la excepción y se ocupa de forma interna (como en el segundo ejemplo), entonces no hay necesidad de incluir una cláusula throws.

7

El código que examinó no es ideal. Debe:

  1. Captura la excepción y manipúlelo; en cuyo caso el throws es innecesario.

  2. Eliminar el try/catch; en cuyo caso la Excepción será manejada por un método de llamada .

  3. captura la excepción, posiblemente realizar algún tipo de acción y luego volver a lanzar la excepción (no sólo el mensaje)

1

El código que envió está mal, debe lanzar una excepción si se captura de una específica excepción para manejar IOException pero lanzando excepciones no atrapadas.

Algo así como:

public void method() throws Exception{ 
    try{ 
      BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
    }catch(IOException e){ 
      System.out.println(e.getMessage()); 
    } 
} 

o

public void method(){ 
    try{ 
      BufferedReader br = new BufferedReader(new FileReader("file.txt")); 
    }catch(IOException e){ 
      System.out.println("Catching IOException"); 
      System.out.println(e.getMessage()); 
    }catch(Exception e){ 
      System.out.println("Catching any other Exceptions like NullPontException, FileNotFoundExceptioon, etc."); 
      System.out.println(e.getMessage()); 
    } 

}

0

Ésta no es una respuesta, pero un comentario, pero yo no podía escribir un comentario con un código de formato, por lo aquí está el comentario.

permite decir que hay

public static void main(String[] args) { 
    try { 
    // do nothing or throw a RuntimeException 
    throw new RuntimeException("test"); 
    } catch (Exception e) { 
    System.out.println(e.getMessage()); 
    throw e; 
    } 
} 

La salida es

test 
Exception in thread "main" java.lang.RuntimeException: test 
    at MyClass.main(MyClass.java:10) 

Ese método no declara ninguna "tiros" Excepciones, sino que los tiros! El truco es que las excepciones lanzadas son RuntimeExceptions (sin marcar) que no son necesarias para ser declaradas en el método. Es un poco engañoso para el lector del método, ya que todo lo que ve es un "tiro e"; declaración, pero ninguna declaración de la lanza excepción

Ahora, si tenemos

public static void main(String[] args) throws Exception { 
    try { 
    throw new Exception("test"); 
    } catch (Exception e) { 
    System.out.println(e.getMessage()); 
    throw e; 
    } 
} 

Debemos declarar la "tira" excepciones en el método de lo contrario se obtiene un error de compilación.

Cuestiones relacionadas