In C si fanno una serie di controlli prima di chiamare una funzione che potrebbe far crashare il programma. In Java si preferisce utilizzare una tecnica più moderna, prima si esegue il codice, se puoi questo genera un errore lo si gestisce senza far crashare il programma. Come si fa? Vediamo subito!
Il codice a rischio di errore viene scritto in un blocco try , al di sotto di esso si inserisce il blocco catch dove si gestiscono gli eventuali errori ricevuti. Vediamo un esempio:
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date j = new Date();
//Assegno null a j, in modo da far generare un'eccezione
j = null;
try{
//Questa riga fa generare una NullPointerException
j.getTime();
}
catch(Exception e){
//Catturo l'eccezione e la stampo
System.out.println("Errore: " + e);
}
//Ciao viene eseguito comunque, il programma non crasha
System.out.println("CIAO");
}
}
Qui assegno null a j, ma il programma non crasha perchè l’eccezione viene gestita.
Exception rappresenta un’eccezione generale, è sempre buona cosa specificare il tipo di eccezione per evitare comportamenti che non ci aspettiamo dal codice. Sempre per lo stesso motivo è buona cosa usare diversi catch per ogni tipo di eccezione.
import java.util.Date;
public class Main {
public static void main(String[] args) {
Date j = new Date();
//Assegno null a j, in modo da far generare un'eccezione
j = null;
try{
//Questa riga fa generare una NullPointerException
j.getTime();
}
catch(NullPointerException e){
//Catturo la NUllPointerExecption e la stampo
System.out.println("Errore: " + e);
}
catch(Exception e){
//Catturo l'eccezione e la stampo
System.out.println("Questo non dovrebbe succedere");
}
//Ciao viene eseguito comunque, il programma non crasha
System.out.println("CIAO");
}
}
Errore: java.lang.NullPointerException: Cannot invoke "java.util.Date.getTime()" because "j" is null
CIAO
L’Aggiunta del blocco finally ci permette di eseguire delle operazioni dopo il try anche se si genera un’eccezione. Questo può ci risultarci molto utile quando dobbiamo avviare un server e dobbiamo poi chiuderlo. Vediamo un breve esempio.
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class Main {
public static void main(String[] args) {
try{
//Creo un server
ServerSocket server = new ServerSocket(5000);
try{
//Aspetto un client
Socket socket = server.accept();
DataOutputStream stream = new DataOutputStream(socket.getOutputStream());
//Gli mando 'Ciao'
stream.writeUTF("Ciao");
//chiudo la connessione
stream.close();
socket.close();
}
catch(SocketTimeoutException e){
System.out.println("Errore di Timeout");
}
catch(IOException e){
System.out.println("Errore di IO");
}
finally{
//chiudo il server
server.close();
}
}
catch(IOException e){
System.out.println("Il server si è chiuso per errore :( ");
}
catch(Exception e){
System.out.println("Qualcosa è andato storto :( ");
}
}
}