How to "fix" an exception?

Asked

Viewed 156 times

2

We can treat an exception thrown by a line of code in order not to let the program break, but how we can fix it?

Scanner sc = new Scanner(System.in);

try {
    String[] vect = new String[1];
    vect[0] = "Maria";

    int posicao = sc.nextInt();
    System.out.println(vect[posicao]);
}
catch(IndexOutOfBoundsException e) {
    System.out.println("Posição inacessível !");
}

If any value is entered in the variable posicao other than 0 will cast the exception of catch, but how can we give the option to type this variable again?

2 answers

4

Instead of trying to "fix" the exception after it happens, you could simply prevent it from happening.

In this case, it would be sufficient to test the position by checking whether the value is valid or not. And if it is not, you ask that this be re-typed, until it is valid. For this we can use a while (true):

int posicao;
System.out.println("Digite o valor da posição:");
while (true) {
    posicao = sc.nextInt();
    if (posicao >= 0 && posicao < vect.length) {
        break; // valor da posição válido, pode sair do while
    } else {
        System.out.println("Valor inválido, digite outro valor:");
    }
}

System.out.println(vect[posicao]);

The while(true) is a way to make a loop infinity. Then the value of posicao is read, and if it is greater than or equal to zero and smaller than the size of the array (vect.length) - that is, it has a value that will not launch IndexOutOfBoundsException - I use the break, to get out of while.

If the value is invalid (negative or larger than the size of the array - that is, any value you throw IndexOutOfBoundsException), the while continues running, and another value is requested, until a valid value is entered.


Like the if has already ensured that the value of posicao is valid, you can even withdraw the try/catch(IndexOutOfBoundsException).

However, if you want to increment the code, you can capture java.util.InputMismatchException, which is the exception launched by nextInt() if something other than an integer is entered:

int posicao;
System.out.println("Digite o valor da posição:");
while (true) {
    try {
        posicao = sc.nextInt();
        if (posicao >= 0 && posicao < vect.length) {
            break; // valor da posição válido, pode sair do while
        } else {
            System.out.println("Valor inválido, digite outro valor:");
        }
    } catch (InputMismatchException e) {
        sc.nextLine(); // limpar o buffer
        System.out.println("Valor digitado não é um número inteiro, digite outro valor:");
    }
}

System.out.println(vect[posicao]);

Within the try I keep doing the same checks on the value of posicao. If something other than an integer is typed (such as abc xyz or even 1.234), the method nextInt() spear one InputMismatchException.

Within the catch I call nextLine() for "clear" the buffer of Scanner, and then inform the user what happened and ask him to type the value again (and the while continues running until a valid value is entered).


You are tempted use the exception to control the program flow, but in this case it is not necessary. It is possible to do the necessary checks and logics without needing it, using only the basic language structures (if, while, etc.).

Except, of course, in the case of InputMismatchException, since this exception is the way the method nextInt() has to indicate that it could not read an integer. But in the case of IndexOutOfBoundsException, doesn’t need the try/catch to do what you need.

  • 1

    Yes, I fully agree that the indiscriminate use of exceptions is terrible... Even I am of the same opinion, programming so that it manages less than possible Exception, and many like java.lang.Arithmeticexception can be solved with just one " if ". What I wanted to know (sorry I’m not specific) is how to "fix" an exception that was exceptionally launched, I used the above example to illustrate, pretend that this is an exceptional case... We can only "flag" ?

  • 1

    @Kevinricci It depends on the type of error and what you need/intend to do. In your example, the exception could be avoided by checking the value of posicao. In my example with InputMismatchException, the exception is the only way to know that nextInt failed, and the "solution" was to ask you to enter another number (but it could also be exit from the program, or qq another action you wanted). Each case is a case. Maybe this question help you - even, in the first answer there are several other interesting links

  • I understood perfectly, but in your case of your example you are using other flow controllers to control a flow controller (Try/catch), the question I want to get at is: by itself the exception handling does not have any recursiveness to actually treat the problem ? It’s just to tell the show "hey buddy, could you make an exception here, I’m warning you not to break beauty ?" but simply does not solve the possible error functionally if it occurs ?

  • It allows the program to continue, right, but if the program needs that information that the error occurred and it simply does not exist because it has released an exception, the program would release a series of exceptions in chain soon after ?

  • @Kevinricci The exception only indicates that something wrong has happened, but what to do if it occurs depends on each case. For example, if you have another way to get the information you need, do it. If not, a decision must be made: can I proceed with the program without that information? If I can’t, I report it and/or close the program. The exception only indicates what happened, but the decision of what to do with it is the programmer’s, and - again - each case is a case.

  • Using your example, if the program needs information but it does not exist pq an error occurred. The exception alone has no way of knowing that that information is necessary - this is a question of the logic of the program, which only the programmer knows, so only he knows what action to take when the exception occurs. Is there another way to get this information? Can I use some other value? Is there any way to proceed without the information? There is no way and the best is to terminate the program (or ask the user to "try again")? This decision is of who program, the exception alone has no way to decide this

  • Well, I think my question has been answered, and that reinforces the idea that exceptions should not be used without circumspection, it is costly for what I’m seeing and, in addition, it can affect performance

Show 2 more comments

3

To solve your problem just use an Infinite Loop and allow your stop with the Return only when the actions you wish to happen, if there is an exception it will give a Continue and return to the beginning of the loop

while(true) {
    System.out.println("Digite a posição");
    Scanner sc = new Scanner(System.in);

    try {
        String[] vect = new String[1];
        vect[0] = "Maria";

        int posicao = sc.nextInt();
        System.out.println(vect[posicao]);
        return;
    } catch (IndexOutOfBoundsException e) {
        System.out.println("Posição inacessível !");
        continue;
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.