Situazioni anomale a run-time

Java è un linguaggio fortemente tipato: molti errori sono individuati dal compilatore (sintassi, tipi, restituzione di valori), ma non tutti...

Si possono verificare varie situazioni impreviste o anomale durante l'esecuzione di un programma (tipicamente dati errati in input, errori di programmazione, ma anche guasti) che possono causarne la brutale interruzione (fallimento).

Un programma ben scritto dovrebbe prevedere tali eventualità inserendo delle istruzioni per individuare le anomalie e ripristinare una situazione corretta.

In Java abbiamo a disposizione un meccanismo di gestione delle eccezioni che è:

  • ben integrato con gli aspetti orientati ad oggetti,

  •  
  • flessibile e potente,

  •  
  • modificabile dall'utente.
Vediamo alcune di queste situazioni anomale che si possono verificare anche in semplici programmi.



Out of bounds 

Accesso ad un elemento inesistente di un array [OutOfBounds]:
 
public class OutOfBounds { 
    public static void main(String [] args){
        int [] array = new int [5];
        for (int i = 0; i < array.length; i++) { 
            array[i] = (int) (100 * Math.random());
        }

        System.out.println("Contenuto dell'array:");

        // Errore nella guardia del for 
        for (int i = 0; i <= array.length; i++) {
            System.out.println(array[i]);
        }
    }
}

Si tratta di un  errore di programmazione: correggere il "<=" in "<" nella guardia del secondo for.

Questo errore potrebbe (anzi dovrebbe) essere evitato dal programmatore! Ma non può essere segnalato dal compilatore.




Errori aritmetici

Divisione per zero [DivideByZero] (si fornisca 0 come input):
 
public class DivideByZero {
    public static  void main(String[] args) {
        int x = 60; // Cosa succede se si dichiara "double"?
        // double x = -60; 
        // Cosa cambia se si inizializza a 0?
        // double x = 0; 
        int y; 
        do { 
            System.out.println("Scrivi un intero (negativo per finire): ");
            y = Input.readInt();
            if (y >= 0) {
                System.out.println("Risultato di "+x+"/"+y+":"); 
                System.out.println(x/y);
            } 
        } while (y >= 0); 
    }
}

Si tratta spesso di mancanza di controlli sull'input dell'utente, indice di codice poco robusto.

Curiosità: se si dichiara x di tipo double nel programma di sopra, e si fornisce in input 0, non viene segnalato un errore ma viene restituita una costante speciale. Infatti le operazioni tra valori in virgola mobile non lanciano eccezioni perché sono conformi allo standard IEEE 754. (Provate a vedere come viene valutata l'espressione 0.0/0).
Per approfondimenti consultare Java Language Specification.




Riferimenti null

Invocazione di un metodo su una variabile il cui valore è null [NullPointer]:
 
public class NullPointer { 
    public static void main(String [] args) {
        Object o = null;
        System.out.println(o); 
        System.out.println(o.toString()); 
    }
}



Errori di cast

Fallimento di un cast: a tempo di esecuzione, una variabile non è legata a un oggetto del tipo dichiarato [ClassCast]:
 
public class ClassCast { 
    public static void main(String [] args) {
        Object o = new Object(); 
        System.out.println(o); 
        System.out.println(); 
        System.out.println((String) o);
    }
}

 




Errori di formato

Fallimento dovuto ad un formato non corretto durante la conversione di una stringa in intero (la lettera "O" è stata digitata al posto della cifra "0") [NumberFormat]:
 
public class NumberFormat { 
    public static void main(String[] args) {
        int x = Integer.parseInt("1O2"); 
        // la seconda cifra sembra 0 ma e' la lettera O
    }
}

 




Altri errori

  • Tentativi di accedere a file inesistenti;

  •  
  • Fine inaspettata di un file durante la lettura;

  •  
  • Errore hardware accedendo a un disco; 

  •  
  • Chiusura inattesa di una connessione remota...