Java disposa d’un mecanisme de capturar ( catch) certs tipus d’errors que només poden ser detectats en temps d’execució de programa.
Els exemples més comuns que podem anomenar d’excepcions:
- Tractar de convertir sencer un String que no conté valors numèrics.
- Tractar de dividir per zero.
- Obre un arxiu de text inexistent o que es troba bloquejat per una altra aplicació.
- connectar amb un servidor de base de dades que no es troba actiu.
- Accedir a subíndexs de vectors i matrius fora de rang.
La captura d’excepcions ens permet crear programes molt més robustos i tolerant a falles que ocorren en escasses situacions, però en cas que es presentin disposem d’un algoritme alternatiu per reaccionar a aquesta situació evitant que el programa finalitzi la seva execució.
Veu rems un exemple sense captura d’excepcions i després la sintaxi implementant la seva captura.
Problema:
Realitzar la càrrega d’un nombre enter per teclat i imprimir el seu quadrat.
programa:
import java.util.Scanner;public class CuadradoNumero { public static void main(String ar) { Scanner teclado = new Scanner(System.in); int num; System.out.print("Ingrese un valor entero:"); num = teclado.nextInt(); int cuadrado = num * num; System.out.print("El cuadrado de " + num + " es " + cuadrado); }}
Si executem el programa i l’operador ingressa un String en lloc d’un sencer es genera una excepció i el programa s’atura en forma immediata :
a
el programa no s’executa més instruccions després de la línia 8 de l’mètode main. S’informa el nom d’excepció generada: java.util.InputMismatchException, és a dir se’ns informa el nom de classe d’excepció i el paquet que la conté: java.util
El primer que podem dir és que aquest tipus d’excepcions no són obligatòries capturar-les, però com veiem si el nostre usuari de el programa en forma freqüent s’equivoca i càrrega cadenes en lloc d’enters el programa s’atura i requereix que el torni a executar.
Podem implementar un programa més robust si capturem l’excepció InputMismatchException i l’informem a l’usuari que ha d’ingressar un enter obligatòriament.
Vegem ara la sintaxi de el mateix programa però capturant l’excepció:
import java.util.InputMismatchException;import java.util.Scanner;public class CuadradoNumero { public static void main(String ar) { Scanner teclado = new Scanner(System.in); int num; try { System.out.print("Ingrese un valor entero:"); num = teclado.nextInt(); int cuadrado = num * num; System.out.print("El cuadrado de " + num + " es " + cuadrado); } catch (InputMismatchException ex) { System.out.println("Debe ingresar obligatoriamente un número entero."); } }}
Per atrapar les excepcions hem tancar en un bloc try les instruccions que generen excepcions, en el nostre cas el mètode ‘nextInt’ de la classe Scanner:
try { System.out.print("Ingrese un valor entero:"); num = teclado.nextInt(); int cuadrado = num * num; System.out.print("El cuadrado de " + num + " es " + cuadrado); }
Tot bloc try requereix que sigui seguit per un bloc catch:
catch (InputMismatchException ex) { System.out.println("Debe ingresar obligatoriamente un número entero."); }
Després de la paraula clau catch s’indica entre parèntesis el nom d’un paràmetre qualsevol (en el nostre cas en diem ‘ex’) i el nom de l’excepció a capturar.
el bloc catch normalment no s’executa llevat dels casos excepcionals que d’aquí a el bloc try informa que es va disparar aquesta excepció.
Ara si executem el programa i l’operador ingressa un String en lloc d’un sencer el nostre programa no s’atura sinó se l’informa el tipus d’error que va cometre l’usuari:
a
quan es dispara una excepció les instruccions que hi ha després de l’mètode que la va disparar no s’executen:
num = teclado.nextInt(); int cuadrado = num * num; System.out.print("El cuadrado de " + num + " es " + cuadrado);
la dues instruccions després de trucar a l’mètode ‘nextInt’ no s’executen si aquest mètode eleva l’excepció.
Podem modificar ara el nostre programa encara més perquè no finalitzi fins que carregui un valor sencer:
import java.util.InputMismatchException;import java.util.Scanner;public class CuadradoNumero { public static void main(String ar) { Scanner teclado = new Scanner(System.in); int num; boolean continua; do { try { continua = false; System.out.print("Ingrese un valor entero:"); num = teclado.nextInt(); int cuadrado = num * num; System.out.print("El cuadrado de " + num + " es " + cuadrado); } catch (InputMismatchException ex) { System.out.println("Debe ingresar obligatoriamente un número entero."); teclado.next(); continua = true; } } while (continua); }}
Si i jecutamos aquesta variant de programa, la comanda de la càrrega de l’sencer no finalitzarà fins que ho utilitzant: