¿Por qué es necesario "throws Exception" al llamar a una función?

97
class throwseg1
{
    void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

    void show2() throws Exception  // Why throws is necessary here ?
    {
        show();
    }

    void show3() throws Exception  // Why throws is necessary here ?
    {
        show2();
    }

    public static void main(String s[]) throws Exception  // Why throws is necessary here ?
    {
        throwseg1 o1 = new throwseg1();
        o1.show3();
    }
}

¿Por qué los informes del compilador que los métodos show2(), show3()y main()tener

excepción no informada Excepción que debe detectarse o declararse para ser lanzada

cuando elimino throws Exceptionde estos métodos?

nr5
fuente
2
@PaulTomblin main ciertamente se puede declarar para lanzar Exception. Si es así, la JVM se cerrará. Esto es lo más cercano a ignorarlo como lo permitirá el compilador.
Taymon
Cuando se lanza el método llamado ( Methdod1 ) Exception, tenemos que definir el método de llamada ( Method2 ) con throws Exception; si no manejamos esa excepción en el método de llamada. El propósito de esto es dar mano a mano con el método de llamada ( metodo3 ) de Método2 que una excepción se puede producir por el Método 2 y se debe manejar desde aquí, de lo contrario puede interrumpir su programa.
Rito
De manera similar, si Method3 no está manejando la excepción en su cuerpo, entonces tuvo que definir throws Exceptionen la definición de su método para dar pistas sobre su método de llamada. extensión del comentario anterior
Rito

Respuestas:

144

En Java, como ya sabrá, las excepciones se pueden clasificar en dos: una que necesita la throwscláusula o debe manejarse si no especifica una y otra que no. Ahora, vea la siguiente figura:

ingrese la descripción de la imagen aquí

En Java, puede lanzar cualquier cosa que amplíe la Throwableclase. Sin embargo, no es necesario especificar una throwscláusula para todas las clases. Específicamente, las clases que son o bien una Erroro RuntimeExceptiono cualquiera de las subclases de estos dos. En su caso, Exceptionno es una subclase de Erroro RuntimeException. Por lo tanto, es una excepción marcada y debe especificarse en la throwscláusula, si no maneja esa excepción en particular. Por eso necesitabas la throwscláusula.


Desde el tutorial de Java :

Una excepción es un evento, que ocurre durante la ejecución de un programa, que interrumpe el flujo normal de las instrucciones del programa.

Ahora, como sabe, las excepciones se clasifican en dos: marcadas y no marcadas. ¿Por qué esta clasificación?

Excepción marcada: Se utilizan para representar problemas que se pueden recuperar durante la ejecución del programa. Por lo general, no son culpa del programador. Por ejemplo, un archivo especificado por el usuario no es legible, o no hay conexión de red disponible, etc., en todos estos casos, nuestro programa no necesita salir, sino que puede tomar acciones como alertar al usuario, o entrar en una reserva. mecanismo (como trabajar sin conexión cuando la red no está disponible), etc.

Excepciones sin marcar : nuevamente se pueden dividir en dos: Errores y Excepciones en tiempo de ejecución. Una de las razones por las que no deben estar marcados es que son numerosos en número y, si se requiere manejarlos, saturará nuestro programa y reducirá su claridad. La otra razón es:

  • Excepciones en tiempo de ejecución: generalmente ocurren debido a una falla del programador. Por ejemplo, si ArithmeticExceptionocurre una división por cero o ocurre una ArrayIndexOutOfBoundsException, es porque no somos lo suficientemente cuidadosos en nuestra codificación. Suelen ocurrir debido a algunos errores en la lógica de nuestro programa. Por lo tanto, deben borrarse antes de que nuestro programa entre en modo de producción. Están desmarcados en el sentido de que nuestro programa debe fallar cuando se produzca, para que los programadores podamos resolverlo en el momento del desarrollo y testeo.

  • Errores: Los errores son situaciones de las que normalmente el programa no puede recuperarse. Por ejemplo, si StackOverflowErrorocurre un , nuestro programa no puede hacer mucho, como aumentar el tamaño de la pila de llamadas a funciones del programa. O si OutOfMemoryErrorocurre una , no podemos hacer mucho para aumentar la cantidad de RAM disponible para nuestro programa. En tales casos, es mejor salir del programa. Es por eso que se hacen sin control.

Para obtener información detallada, consulte:

Jomoos
fuente
lo que obtuve de su respuesta es que la clase Error y sus sublaclases y la clase RuntimeException y sus subclases, se encuentran bajo una excepción no verificada (como System.out.println (5/0); no hay necesidad de lanzar ya que es un excepción de tiempo de ejecución, pero aún podemos aplicar try catch) y la clase Exception está marcada, por lo que debemos declarar la cláusula throws en ese método y cada método que lo llame
nr5
Una pregunta más: si las excepciones se clasifican en no marcadas y marcadas, especialmente las no marcadas (errores de tiempo de ejecución) para evitar más errores durante el tiempo de compilación.
nr5
@Jomoos: digamos que el código dentro de un método arroja IOException. Entonces, ¿está bien poner "throws Exception" en la declaración del método?
MasterJoe
Oh. Ahora lo entiendo. hay una excepción a las reglas de la jerarquía de excepciones. Hace. Perfecto. Sentido. Gracias Java.
JJS
25

Java requiere que maneje o declare todas las excepciones. Si no está manejando una excepción usando un bloque try / catch, debe declararse en la firma del método.

Por ejemplo:

class throwseg1 {
    void show() throws Exception {
        throw new Exception();
    }
}

Debe escribirse como:

class throwseg1 {
    void show() {
        try {
            throw new Exception();
        } catch(Exception e) {
            // code to handle the exception
        }
    }
}

De esta manera puede deshacerse de la declaración "throws Exception" en la declaración del método.

jebar8
fuente
7
Todas las excepciones que no son subclases de RuntimeException, es decir.
yshavit
si hay alguna otra clase como Exception que está marcada?
nr5
1
¿Qué quieres decir? Dado que todos los objetos de excepción tienen "Exception" como su clase base, si detecta un objeto "Exception" (como en mi ejemplo), detectará cualquier excepción que se lance. Para ser más específico (dado que diferentes excepciones probablemente requerirán diferentes formas de manejar las cosas), debe tener varios bloques de captura.
jebar8
si tuviera que decir que las excepciones marcadas deben manejarse en tiempo de compilación y detectarse en tiempo de ejecución. Estoy en lo cierto? en caso afirmativo, entonces redactar la misma oración para la excepción sin marcar sería?
nr5
@ jebar8: confunde Java con .NET: en Java, los elementos lanzables deben heredar Throwable(la herencia Exceptiontambién funciona, porque se extiende Throwable, pero no es obligatorio).
BrainSlugs83
4

Exceptiones una clase de excepción comprobada. Por lo tanto, cualquier código que llame a un método que declare que throws Exceptiondebe manejarlo o declararlo.

Taymon
fuente
Se declara que todos los métodos de la cadena lanzan Exception, incluido main. Entonces, ¿dónde está el problema?
Paul Tomblin
@PaulTomblin estoy preguntando por qué es necesario escribir throws exception en las funciones de llamada, llamando a una función que arroja una excepción
nr5
Ok, no entendí por qué preguntaba acerca de un error del compilador que en realidad no estaba obteniendo del código que publicó. Esa es una forma extraña de preguntar.
Paul Tomblin
4

La throws Exceptiondeclaración es una forma automatizada de realizar un seguimiento de los métodos que pueden generar una excepción por razones anticipadas pero inevitables. La declaración suele ser específica sobre el tipo o tipos de excepciones que se pueden generar, como throws IOExceptiono throws IOException, MyException.

Todos tenemos o eventualmente escribiremos código que se detiene inesperadamente e informa una excepción debido a algo que no anticipamos antes de ejecutar el programa, como la división por cero o el índice fuera de los límites. Dado que el método no esperaba los errores, no podían "detectarse" ni manejarse con una cláusula try catch. Cualquier usuario desprevenido del método tampoco conocería esta posibilidad y sus programas también se detendrían.

Cuando el programador sabe que pueden ocurrir ciertos tipos de errores pero le gustaría manejar estas excepciones fuera del método, el método puede "lanzar" uno o más tipos de excepciones al método de llamada en lugar de manejarlas. Si el programador no declara que el método (podría) lanzar una excepción (o si Java no tiene la capacidad de declararlo), el compilador no podría saberlo y dependerá del futuro usuario del método conocerlo, captura y maneja cualquier excepción que el método pueda generar. Dado que los programas pueden tener muchas capas de métodos escritos por muchos programas diferentes, resulta difícil (imposible) realizar un seguimiento de los métodos que pueden generar excepciones.

Aunque Java tiene la capacidad de declarar excepciones, aún puede escribir un nuevo método con excepciones no controladas y no declaradas, y Java lo compilará y podrá ejecutarlo y esperar lo mejor. Lo que Java no le permitirá hacer es compilar su nuevo método si usa un método que ha sido declarado como lanzando excepciones, a menos que maneje las excepciones declaradas en su método o declare que su método arroja lo mismo excepción (es) o si hay varias excepciones, puede manejar algunas y lanzar el resto.

Cuando un programador declara que el método genera un tipo específico de excepción, es solo una forma automatizada de advertir a otros programadores que utilizan el método de que es posible una excepción. Luego, el programador puede decidir manejar la excepción o pasar la advertencia declarando que el método de llamada también lanza la misma excepción. Dado que el compilador ha sido advertido de que la excepción es posible en este nuevo método, puede verificar automáticamente si los futuros llamadores del nuevo método manejan la excepción o la declaran y obligan a que suceda una u otra.

Lo bueno de este tipo de solución es que cuando el compilador informa Error: Unhandled exception type java.io.IOException, da el archivo y el número de línea del método que se declaró para lanzar la excepción. A continuación, puede optar por simplemente pasar la pelota y declarar que su método también "lanza IOException". Esto se puede hacer hasta el método principal, donde luego haría que el programa se detuviera e informara la excepción al usuario. Sin embargo, es mejor detectar la excepción y tratarla de una manera agradable, como explicarle al usuario lo que ha sucedido y cómo solucionarlo. Cuando un método detecta y maneja la excepción, ya no tiene que declarar la excepción. La pelota se detiene allí, por así decirlo.

dansalmo
fuente
0
package javaexception;


public class JavaException {
   void show() throws Exception
    {
        throw new Exception("my.own.Exception");
    }

void show2() throws Exception  // Why throws is necessary here ?
{
    show();
}

void show3() throws Exception  // Why throws is necessary here ?
{
    show2();
}
public static void main(String[] args) {

   JavaException a = new JavaException();

   try{
   a.show3();
   }catch(Exception e){
       System.out.println(e.getMessage());
   }
}

Solo pequeños cambios en su programa. Lo que parece ser malinterpretado por muchos con respecto al problema principal, es que cada vez que lanza una excepción, debe manejarla, no es necesario en el mismo lugar (por ejemplo, el método show1,2,3 en su programa) pero debe al principio el método de llamada dentro del 'principal'. en una palabra, hay 'lanzar', debe haber 'atrapar / intentar', incluso si no es el mismo método donde ocurre la excepción.

tawess
fuente
0
void show() throws Exception
{
    throw new Exception("my.own.Exception");
}

Como hay una excepción marcada en el método show (), que no se maneja en ese método, usamos la palabra clave throws para propagar la excepción.

void show2() throws Exception //Why throws is necessary here ?
{
show();
}

Dado que está utilizando el método show () en el método show2 () y ha propagado la excepción, al menos debería manejar aquí. Si no está manejando la excepción aquí, entonces está usando la palabra clave throws. Entonces esa es la razón para usar la palabra clave throws en la firma del método.

Aditya
fuente
0

Si propaga la excepción declarando la directiva throws en la firma del método actual, entonces en algún lugar de la línea o pila de llamadas se debe usar una construcción try / catch para manejar la excepción.

Beaumont Muni
fuente
Este comentario debe agregarse a la sección de comentarios ya que no proporciona una respuesta verificable ni un ejemplo de una. - stackoverflow.com/help/how-to-answer
Paul Dawson
-1

Básicamente, si no está manejando la excepción en el mismo lugar donde la está lanzando, entonces puede usar "throws exception" en la definición de la función.

Shahzeb Sheikh
fuente