Diferència entre revisions de la pàgina «DAM-M3-UF5. Control d'excepcions»
(→Propagació d'Excepcions) |
(→Excepcions) |
||
(Hi ha una revisió intermèdia del mateix usuari que no es mostren) | |||
Línia 21: | Línia 21: | ||
* ClassCastException | * ClassCastException | ||
− | + | https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/RuntimeException.html | |
=== Try / Catch / Finally === | === Try / Catch / Finally === | ||
Línia 169: | Línia 169: | ||
En principi no cal sobreescriure cap mètode (tot i que si no es fa és una tonteria crear una nova classe). | En principi no cal sobreescriure cap mètode (tot i que si no es fa és una tonteria crear una nova classe). | ||
− | <pre> | + | <html><pre><code class='java'> |
public class ExceptionMeva extends Exception { | public class ExceptionMeva extends Exception { | ||
Línia 200: | Línia 200: | ||
} | } | ||
− | </pre> | + | </code></pre></html> |
Revisió de 18:05, 5 feb 2021
torna M3 - Programació
Contingut
Excepcions
Una excepció és un esdeveniment anòmal (imprevist) durant l’execució d’un programa que es pot tractar per evitar la finalització del programa.
No s’ha de confondre les excepcions amb els errors, aquests són irrecuperables, fruit d'una implementació incorrecte o d'algun problema extern, i haurien de finalitzar el programa.
Les excepcions per contra, es poden controlar, Java gestiona múltiples tipus d’excepcions, apuntador a null, array fora de límits, etc.. i també permet definir-ne de pròpies.
Classe Throwable,
- Subclasse Error: problemes crítics però poc habituals
- Subclasse Exception: situacions que cal gestionar
- Subclasse RunTimeException: problemes MV, es poden gestionar també però són imprevisibles
Així les excepcions segueixen també l'arbre d'herència de Java, alguns exemples
- NullPointerException
- IndexOutOfBoundsException
- ClassCastException
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/RuntimeException.html
Try / Catch / Finally
El control d’excepcions serveixen per gestionar els errors en temps d’execució i evitar la finalització del programa en situacions anòmales.
El programa executa les instruccions interiors a try, si es produeix qualsevol error llança una excepció que captura catch, i així podem controlar l’error sense finalitzar el programa de manera forçosa.
No s'executa cap instrucció dins del try posterior a la que genera un error.
Les instruccions dins el finally s’executen sempre hi hagi o no excepció.
public static void main(String[] args) {
int opcio;
try {
opcio = Integer.parseInt(args[0]);
switch(opcio) {
case 0: System.out.println("Has introduït 0");
break;
case 1: System.out.println("Has introduït 1");
break;
default: System.out.println("????");
}
} catch (Exception e) {
System.out.println("Error en els paràmetres --> " + args[0]);
System.exit(0);
} finally {
System.out.println( "Final" );
}
}
throw / throws
La instrucció throw permet llençar excepcions pròpies.
public static void prova() {
throw new NullPointerException("Texte de l’excepcio");
}
public static void main(String[] args) {
try {
prova();
System.out.println("No s'executa mai");
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
}
El paràmetre throws propaga possibles excepcions que genera un mètode, pròpies o generades pels mètodes que crida.
Serveix per advertir als altres mètodes que l’invoquen de les excepcions que aquest pot produir.
public static void prova1() throws Exception {
throw new NullPointerException("Texte de l’excepcio 1");
}
public static void main(String[] args) {
int opcio = Integer.parseInt(args[0]);
prova1(); // Error
try {
prova1();
System.out.println("No s'executa mai");
} catch (Exception e) {
System.out.println("Error " + e.getMessage());
}
}
Propagació d'Excepcions
Les excepcions es propaguen diferent segons:
- Classe RunTimeException i subclasses unchecked exceptions: Es propaguen automàticament, no és obligatori realitzar cap acció (però pot ser recomanable)
- Classe Exception i subclasses (Però no de RunTimeException) checked exceptions: No es propaguen automàticament, cal propagar-les o controlar-les
- L'ús d'aquests mètodes obliga a controlar l'excepció
- Opció 1. Usant try/catch
- Opció 2. Marcant el propi mètode com a throws
- L'ús d'aquests mètodes obliga a controlar l'excepció
public static void prova0() { // Error
throw new Exception("Texte de l’excepcio");
}
public static void prova1() throws Exception { // Ok
throw new Exception("Texte de l’excepcio");
}
public static void prova2() throws NullPointerException { // Ok
throw new NullPointerException("Texte de l’excepcio");
}
public static void prova3() { // Ok
throw new NullPointerException("Texte de l’excepcio");
}
public static void main(String[] args) {
prova1();
prova2();
prova3();
}
Així les excepcions es propaguen en la pila de crides a mètodes fins que algú les captura (try / catch) o bé arriben a la crida principal i finalitzen l'execució.
Per exemple suposa la següent pila de crides a mètodes
primer() => segon() => tercer()
En cas d’error en la crida tercer() l’excepció es propagarà a les altres crides descendentment fins que alguna el capturi o arribi al programa principal.
public static void main(String[] args) {
primer();
}
public static void primer() {
segon();
}
public static void segon() {
throw new NullPointerException();
}
Creació d'Excepcions
Per crear excepcions pròpies només cal heretar d'alguna excepció, en general i a falta de cap requeriment concret hi ha dues opcions:
- Volem que es propaguin automàticament: Hereten de RunTimeException
- Volem que un control estricte per part dels usuaris de la classe: Heretar de Exception
En principi no cal sobreescriure cap mètode (tot i que si no es fa és una tonteria crear una nova classe).
public class ExceptionMeva extends Exception {
public ExceptionMeva(String message) {
super(message);
}
public String getLocalizedMessage() {
String error = super.getMessage();
error += "\nMissatge personalitzat";
return error;
}
}
// Per usar la nova classe
public static void prova4() throws ExceptionMeva {
throw new ExceptionMeva("Ha passat una catàstrofe!!");
}
public static void main(String[] args) {
try {
prova4();
} catch (ExceptionMeva e) {
// TODO Auto-generated catch block
System.out.println(e.getLocalizedMessage());
e.printStackTrace();
}
}