Good morning.
You can launch an exception from anywhere in the program, regardless of whether it is captured for a catch
. To do this you must create the exception and throw it with the reserved word throw
in the following way:
throw new EmptyStackException();
This will cause the block catch
with the type of the appropriate exception to be executed. To do this, it looks for the stack of calls to the block that can capture it, if there is not, the virtual machine will end the execution of the program when it fails to process the error (propagation of exceptions , What is exception propagation ? ).
Consider the following image:
You can launch with thow
any class that is Throwable's daughter. If you want to throw an exception of type Exception
but do not want to process it you must declare in the function where the excemption is given that must be captured in a higher level (this is not necessary for children of RuntimeException
), this is from the < a href="https://docs.oracle.com/javase/tutorial/essential/exceptions/declaring.html"> following way :
public void FuncionQueNoProcesaExcepciones throws Exception,
MiException {
// ...
}
Now if you want to capture an exception, the structure of an exception handler contains the reserved words try , catch , finally . The structure is as follows:
try {
// codigo que podría lanzar excepciones. Puedes ser distintos
// tipos como IOException, IndexOutOfBoundsException
} catch (IOException excepcion){
// Este bloque solo se ejecuta cuando se lanza una excepcion
// del tipo IOException
} catch (IndexOutOfBoundsException excepcion){
// Este bloque solo se ejecuta cuando se lanza una excepcion
// del tipo IndexOutOfBoundsException
} finally {
// siempre se llama a finally, haya una excepcion o no.
}
Clarifying the function of the try-catch block, responding to:
Is there any way to force the jump, without causing an exception, from inside the try to the catch?
Here are the options:
- Use
throw
to execute the catch
. This takes you out of the normal flow of the program.
-
Use a method in catch
, so that it can be called without throwing an exception. This way you can call it from anywhere, even within the try
(obvious is a method).
public static void main(String[] args) {
String texto = "Desde el try";
try {
// codigo
procesaExcepcion(texto);
// si se llamara desde el catch ...
throw new Exception();
} catch (Exception c) {
texto = "Desde el catch";
procesaExcepcion(texto, c);
}
}
public static void procesaExcepcion(Object... contexto) {
// hacer cosas para procesar la excepcion
System.out.println(contexto[0]);
}
-
Use reflection functions and frameworks to manipulate bytecodes (this is the only way to run catch
without throwing an exception), but this is not easy at all.
Now, your problem does not need a recursive call
"I show a message and recursively call the function"
The correct way to validate an entry is by using the do-while cycle, as follows
java.util.Scanner sc = new java.util.Scanner(System.in);
int variable = -1;
do {
try {
System.out.print("Ingrese una opcion: ");
variable = Integer.parseInt( sc.nextLine() );
} catch( NumberFormatException e ) {
// no es necesario poner algo aqui
}
} while (variable < 1 || variable > 5);
System.out.print(variable);
The above code declares and initializes a variable that stores the number you wish to validate. When trying to convert with parseInt
there are two options: convert or throw an exception.
- If it is converted, the while of the cycle validates that it is among the desired values, if not, the entry is read again.
- In case of exception, the variable is -1, so it is not a valid value and the cycle is repeated.
Now, if you want a shorter code you can change the block:
try {
System.out.print("Ingrese una opcion: ");
variable = Integer.parseInt( sc.nextLine() );
} catch( NumberFormatException e ) {
// no es necesario poner algo aqui
}
for
while (!sc.hasNextInt()) sc.next();
variable = sc.nextInt();
Finally if you have problems with the lines;) you can always write everything in one without spaces:
Scanner s=new Scanner(System.in);
int v=-1;do{while(!s.hasNextInt())s.next();v=s.nextInt();}while(v<1||v>5);