Eccezioni

Exception

Le eccezioni si usano quando la situazione (valore dei parametri, resource) non permette di continuare l'esecuzione normale. Esempio: quando si crea una Line, ciò ha senso solo quando i due punti sono diversi:
class Line {
  Point pt1, pt2;
  Line (Point p, Point q) {
    if (p.equals(q)) {
      //Errore!
    }
    pt1=p;
    pt2=q;
  }
}
Le eccezioni sono oggetti in Java. Esiste una class Exception. Si può creare una eccezione usando il costruttore vuoto new Exception() o il costruttore con una stringa new Exception("message"). Le eccezioni sono sollevate (throw) e un metodo (o un costruttore) che può sollevare un'eccezione deve dirlo.
class Line {
  Point pt1, pt2;
  Line (Point p, Point q) throws Exception {
    if (p.equals(q)) {
      throw new Exception("Not A Line");
    }
    pt1=p;
    pt2=q;

  }
}
Si può essere più specifici e creare le proprie eccezioni.
class NotALine extends Exception {
}

class Line {
  Point pt1, pt2;
  Line (Point p, Point q) throws NotALine {
    if (p.equals(q)) {
      throw new NotALine();
    }
    pt1=p;
    pt2=q;

  }
}
Un metodo o un costruttore possono sollevare più di un tipo di eccezioni:
class NotALine extends Exception {
}
class Uninitialised extends Exception {
}

class Line {
  Point pt1, pt2;
  Line (Point p, Point q) throws Uninitialised, NotALine {
    if (p==null || q == null) {
      throw new Uninitialised();
    }
    if (p.equals(q)) {
      throw new NotALine();
    }
    pt1=p;
    pt2=q;

  }
}

Le eccezioni sono un'alternativa più pulita di quella che consiste nel codificare l'errore nel valore restituito. Esempio:

class Line {
  Point pt1, pt2;
  Line (Point p, Point q) {
    if (!(p==null || q==null || p.equals(q))) {
      pt1=p;
      pt2=q;
    }
  }
}

Try

try {
  <EXPRESSION>
  ...
  <EXPRESSION>
}
catch (<NAME> <NAME>) {
  <EXPRESSION>
  ...
  <EXPRESSION>
}
...
catch (<NAME> <NAME>) {
  <EXPRESSION>
  ...
  <EXPRESSION>
}
finally {
  <EXPRESSION>
  ...
  <EXPRESSION>
}

I catch sono selezionati nel'ordine del programma, non è il più specifico che è scelto.

Il finally è sempre eseguito anche se il try finisce senza eccezioni.

Esempio

Il costruttore di Line può sollevare eccezioni, dunque la definizione di in non va bene:
class Line {
  Point pt1,pt2;
  Line (Point p, Point q) throws Uninitialised, NotALine {
    if (p==null || q == null) {
      throw new Uninitialised();
    }
    if (p.equals(q)) {
      throw new NotALine();
    }
    pt1=p;
    pt2=q;
  }
  int deltaX() {
    return pt1.x-pt2.x;
  }
  int deltaY() {
    return pt1.y-pt2.y;
  }
  boolean parallel(Line l) {
    return (deltaX()*l.deltaY())==(deltaY()*l.deltaX());
  }
  boolean in(Point pt) {
    return parallel(new Line(pt1,pt));
  }
}
Bisogna recuperare le eccezioni usando il try
boolean in(Point pt)  {
  try {
    return parallel(new Line(pt1,pt));
  }
  catch (NotALine e) {
    return true;
  }
  catch (Unintialised e) {
    return false;
  }
}
o
boolean in(Point pt) throws Uninitialised {
  try {
    return parallel(new Line(pt1,pt));
  }
  catch (NotALine e) {
    return true;
  }
  catch (Unintialised e) {
    throw e;
  }
}
o
boolean in(Point pt) throws Uninitialised {
  try {
    return parallel(new Line(pt1,pt));
  }
  catch (NotALine e) {
    return true;
  }
}

Runtime Exception e Error

Per java.lang.RuntimeException e java.lang.Error e per tutte le class che estendono queste class non c'è bisogno di verificare le eccezioni ma si può comunque usare il try.

Subclass di RuntimeException

Subclass di Error

Esempio
static void fillArray(int[] a, int first, int last, int value) {
  for(int i=first; i<last; i++) {
    a[i]=value;
  }
}
Forse andiamo oltre la lunghezza di a:
static void fillArray(int[] a, int first, int last, int value) {
  try {
    for(int i=first; i<last; i++) {
      a[i]=value;
    }
  }
  catch (IndexOutOfBoundsException e) {
  }
}

Esercizi

F1*. Riscrivere il metodo in dall'esercizio D6 in tale mode che se il numero aggiunto è già nella lista, il metodo solleva l'eccezione ListException.

F2*. Riscrivere i metodi getPath e getTree dall'esercizio D7 in tale mode che l'eccezione NotFoundException è sollevata se è richiesto un camino di un sotto-albero che non appartienne all'albero e se è chiesto un sotto-albero con un camino invalido.

F3*. Riscrivere i metodi dall'esercizion C4 in tale modo che ogni problema con la dimensione delle matrice vienne riportato con l'eccezione IllegalDimension}.


Laurent Théry
Last modified: Sun Jun 1 19:57:01 MEST 2003