Gestione delle eccezioni in Java e Bordeaux-Saintes: differenze tra le pagine

(Differenze fra le pagine)
Contenuto cancellato Contenuto aggiunto
AttoBot (discussione | contributi)
m Bot: formattazione dei wikilink
 
Nessun oggetto della modifica
Etichette: Modifica da mobile Modifica da web per mobile
 
Riga 1:
{{S|competizioni ciclistiche}}
{{F|linguaggi di programmazione|febbraio 2013|Voce ampia che manca completamente di Note, Bibliografia, Collegamenti esterni}}
{{Competizione sportiva
{{torna a|Java (linguaggio)}}
|nome = Bordeaux-Saintes
Nel [[linguaggio di programmazione]] [[Programmazione orientata agli oggetti|''object-oriented'']] [[Java (linguaggio)|Java]], il sistema di '''gestione delle eccezioni''' (o '''exception handling''') è costituito da un insieme di costrutti e regole [[sintassi (informatica)|sintattiche]] e [[semantica (informatica)|semantiche]] introdotte allo scopo di rendere più semplice, chiara e sicura la gestione di eventuali ''situazioni anomale'', dette [[eccezione (informatica)|eccezioni]], che si possono verificare durante l'[[esecuzione (informatica)|esecuzione]] di un [[Programma (informatica)|programma]].
|logo =
|dimensioni logo =
|altri nomi =
|sport = Ciclismo su strada
|tipologia = Gara individuale
|categoria = Calendario nazionale
|confederazione =
|nazione = {{FRA}}
|luogo =
|organizzatore =
|direttore =
|cadenza = Annuale
|apertura = marzo
|partecipanti = Variabile
|formato = [[Corsa in linea]]
|fondazione = 1909
|estinzione =
|numero edizioni = 74 <small>(al 2011)</small>
|detentore = {{Bandiera|RUS}} [[Matvey Zubov]]
|maggiori titoli =
|ultima edizione =
|stagione attuale =
|prossima edizione =
}}
La '''Bordeaux-Saintes''' è una [[corsa in linea]] maschile di [[ciclismo su strada]] che si svolge tra [[Bordeaux]] ([[Gironda (dipartimento)|Gironda]]) e [[Saintes]] ([[Charente Marittima]]), in [[Francia]], ogni anno in marzo. Nel [[2005]] ha fatto parte del calendario dell'[[UCI Europe Tour]] nella classe 1.2, dal 2006 è inserita nel calendario nazionale francese.
 
== Albo d'oro ==
L'''exception handling'' di Java deriva direttamente (anche da un punto di vista sintattico) da quello del [[C++|linguaggio C++]]. Tuttavia, il meccanismo di Java deve considerarsi forse più oneroso, ma certamente più sicuro, grazie alla cosiddetta regola dello ''handle or declare'' (gestisci o dichiara), che in sostanza ''obbliga'' il [[programmatore]] a prevedere esplicite contromisure ''per ogni'' situazione anomala (prevedibile).
''Aggiornato all'edizione 2011.''<ref>{{cita web|url=http://www.memoire-du-cyclisme.eu/ligne/cla_bordeaux_saintes.php|titolo=Bordeaux-Saintes (Fra) - Cat. 1.2|lingua=fr|editore=www.memoire-du-cyclisme.eu|accesso=27 dicembre 2011}}</ref>
 
{| class="wikitable" style="font-size:95%"
==Motivazioni==
!Anno
Qualsiasi programma concreto di un certo livello di complessità può incorrere, durante la propria esecuzione, in ''situazioni anomale'' che richiedono di venire trattate eseguendo azioni che differiscono da quello che sarebbe stato, altrimenti, il "[[flusso di esecuzione|flusso]] normale" del programma. Ovviamente, il confine fra "anomalo" o "normale" non è netto. Come esempi di "situazioni anomale", si pensi per esempio all'impossibilità di dialogare con un [[server]] attraverso la rete, o il fatto che il programma cerchi di aprire un [[file]] che non risulta presente su disco, e così via.
!Vincitore
!Secondo
!Terzo
|-
|1909
|{{bandiera|FRA}} [[Ernest Milleroux]]
|{{bandiera|FRA}} [[Paul Hostein]]
|{{bandiera|FRA}} [[Régis de Lavlette]]
|-
|1910-32
|colspan=3 align=center|''non disputato''
|-
|1933
|{{bandiera|FRA}} [[André Gaillot]]
|{{bandiera|FRA}} [[Emile Sainte-Marie]]
|{{bandiera|FRA}} [[Jean-Baptiste Intcegaray]]
|-
|1934
|{{bandiera|FRA}} [[Ernest Terreau]]
|{{bandiera|FRA}} [[Jean-Baptiste Intcegaray]]
|{{bandiera|FRA}} [[Georges Lachat]]
|-
|1935
|{{bandiera|FRA}} [[Robert Béliard]]
|{{bandiera|FRA}} [[Emile Clergeau]]
|{{bandiera|FRA}} [[Gabriel Hargues]]
|-
|1936
|{{bandiera|NLD}} [[Albert Van Schendel]]
|{{bandiera|CHE}} [[Robert Gygi]]
|{{bandiera|FRA}} [[Robert Béliard]]
|-
|1937
|{{bandiera|FRA}} [[Sylvain Marcaillou]]
|{{bandiera|FRA}} [[Roger Pieteraerents]]
|{{bandiera|FRA}} [[Raymond Goubault]]
|-
|1938
|{{bandiera|FRA}} [[André Gaboriaud (ciclista)|André Gaboriaud]]
|{{bandiera|FRA}} [[Raymond Goubault]]
|{{bandiera|FRA}} [[Fernand Beaudut]]
|-
|1939
|{{bandiera|FRA}} [[Fernand Beaudut]]
|{{bandiera|FRA}} [[Jean Taris (ciclista)|Jean Taris]]
|{{bandiera|FRA}} [[Edouard Bouyer]]
|-
|1940-45
|colspan=3 align=center|''non disputato''
|-
|1946
|{{bandiera|FRA}} [[Antoine Latorre]]
|{{bandiera|FRA}} [[Joseph Royo]]
|{{bandiera|FRA}} [[André Bramard]]
|-
|1947
|{{bandiera|FRA}} [[Robert Rippe]]
|{{bandiera|FRA}} [[Roger Durand]]
|{{bandiera|FRA}} [[René Paillier]]
|-
|1948
|{{bandiera|FRA}} [[Albert Dolhats]]
|{{bandiera|FRA}} [[Gérard Villar]]
|{{bandiera|FRA}} [[Raymond Cosse]]
|-
|1949
|{{bandiera|FRA}} [[Jacques Bebenhut]]
|{{bandiera|FRA}} [[Albert Joulin]]
|{{bandiera|FRA}} [[Félix Adriano]]
|-
|1950
|{{bandiera|FRA}} [[Jean Begue]]
|{{bandiera|FRA}} [[André Labeylie]]
|{{bandiera|FRA}} [[Guerrino Cassol]]
|-
|1951
|{{bandiera|FRA}} [[André Darrigade]]
|{{bandiera|FRA}} [[Henry Aubry]]
|{{bandiera|FRA}} [[Pierre Gaudot]]
|-
|1952
|{{bandiera|FRA}} [[Pierre Gaudot]]
|{{bandiera|FRA}} [[Gabriel Gaudin]]
|{{bandiera|FRA}} [[Settimo Perin]]
|-
|1953
|{{bandiera|FRA}} [[Settimo Perin]]
|{{bandiera|ESP 1945-1977}} [[Luis Goya Picassari]]
|{{bandiera|ESP 1945-1977}} [[Félix Bermudez]]
|-
|1954
|{{bandiera|FRA}} [[Maurice Nauleau]]
|{{bandiera|ESP 1945-1977}} [[Luciano Montero Rechou]]
|{{bandiera|FRA}} [[Georges Gay]]
|-
|1955
|{{bandiera|FRA}} [[Jean Dacquay]]
|{{bandiera|FRA}} [[Jacques Lemaitre]]
|{{bandiera|FRA}} [[Georges Gay]]
|-
|1956
|{{bandiera|FRA}} [[Gérard Gaillot]]
|{{bandiera|FRA}} [[André Lesca]]
|{{bandiera|ESP 1945-1977}} [[Luis Goya Picassari]]
|-
|1957
|{{bandiera|FRA}} [[André Lesca]]
|{{bandiera|FRA}} [[Jacques Blanco]]
|{{bandiera|FRA}} [[Maurice Pele]]
|-
|1958
|{{bandiera|FRA}} [[Maurice Pèle]]
|{{bandiera|FRA}} [[Alain Lesca]]
|{{bandiera|FRA}} [[Guy Planas]]
|-
|1959
|{{bandiera|FRA}} [[Robert Verdeun]]
|{{bandiera|FRA}} [[Daniel Walryck]]
|{{bandiera|FRA}} [[Albert Dolhats]]
|-
|1960
|{{bandiera|FRA}} [[Raymond Poulidor]]
|{{bandiera|FRA}} [[Pierre Beuffeuil]]
|{{bandiera|FRA}} [[Robert Verdeun]]
|-
|1961
|{{bandiera|FRA}} [[Fernand Delord]]
|{{bandiera|FRA}} [[René Fournier]]
|{{bandiera|FRA}} [[Raymond Batan]]
|-
|1962
|{{bandiera|FRA}} [[Manuel Manzano]]
|{{bandiera|FRA}} [[Camille Le Menn]]
|{{bandiera|FRA}} [[Fernand Delort]]
|-
|1963
|{{bandiera|FRA}} [[Fernand Delort]]
|{{bandiera|FRA}} [[Michel Gonzales]]
|{{bandiera|FRA}} [[René Fournier]]
|-
|1964
|{{bandiera|FRA}} [[Pierre Le Mellec]]
|{{bandiera|ESP 1945-1977}} [[José María Errandonea]]
|{{bandiera|FRA}} [[Jean Arze]]
|-
|1965
|{{bandiera|FRA}} [[Joseph Groussard]]
|{{bandiera|FRA}} [[Gérard Capdebosq]]
|{{bandiera|FRA}} [[Michel Brux]]
|-
|1966
|{{bandiera|ESP 1945-1977}} [[Domingo Perurena]]
|{{bandiera|FRA}} [[Raymond Delisle]]
|{{bandiera|FRA}} [[Maurice Laforest]]
|-
|1967
|{{bandiera|FRA}} [[Raymond Riotte]]
|{{bandiera|FRA}} [[Francis Campaner]]
|{{bandiera|FRA}} [[André Zimmermann]]
|-
|1968
|{{bandiera|ESP 1945-1977}} [[Gregorio San Miguel]]
|{{bandiera|FRA}} [[Jean-Marie Leblanc]]
|{{bandiera|FRA}} [[Michel Périn (ciclista)|Michel Périn]]
|-
|1969
|{{bandiera|ITA}} [[Renato Rossetto]]
|{{bandiera|BEL}} [[Yvan Francaux]]
|{{bandiera|FRA}} [[Jean-Louis Jageneau]]
|-
|1970
|{{bandiera|FRA}} [[Guy Patour]]
|{{bandiera|GBR}} [[Andrew Raven]]
|{{bandiera|FRA}} [[Marcel Gaffajoli]]
|-
|1971
|{{bandiera|FRA}} [[Claude Magni]]
|{{bandiera|FRA}} [[Alain Bernard (ciclista)|Alain Bernard]]
|{{bandiera|FRA}} [[Claude Chabanel]]
|-
|1972
|{{bandiera|FRA}} [[Christian Ardouin]]
|{{bandiera|FRA}} [[José Philippe]]
|{{bandiera|FRA}} [[Jean Gillet]]
|-
|1973
|{{bandiera|FRA}} [[Jacques Bossis]]
|{{bandiera|FRA}} [[Alain Cigana]]
|{{bandiera|FRA}} [[Jean-François Mainguenaud]]
|-
|1974
|{{bandiera|FRA}} [[Didier Dupuis]]
|{{bandiera|FRA}} [[Didier Godet]]
|{{bandiera|FRA}} [[Jacky Troyard]]
|-
|1975
|{{bandiera|FRA}} [[Didier Bazzo]]
|{{bandiera|FRA}} [[Alain de Carvalho]]
|{{bandiera|GBR}} [[David Wells]]
|-
|1976
|{{bandiera|FRA}} [[Alain Mercadie]]
|{{bandiera|FRA}} [[Jackie Hurou]]
|{{bandiera|FRA}} [[Gérard Simonnot]]
|-
|1977
|{{bandiera|FRA}} [[Didier Lubiato]]
|{{bandiera|FRA}} [[Jean-Marie Nibeaudeau]]
|{{bandiera|FRA}} [[Gérard Cigano]]
|-
|1978
|{{bandiera|FRA}} [[Michel Fedrigo]]
|{{bandiera|FRA}} [[Jean-Marie Corre]]
|{{bandiera|FRA}} [[Jean-Jacques Szkolnyk]]
|-
|1979
|{{bandiera|FRA}} [[Marc Gomez]]
|{{bandiera|FRA}} [[Francis Castaing]]
|{{bandiera|FRA}} [[Michel Fedrigo]]
|-
|1980
|{{bandiera|FRA}} [[Francis Castaing]]
|{{bandiera|FRA}} [[Bernard Huot]]
|{{bandiera|FRA}} [[Michel Dufour]]
|-
|1981
|{{bandiera|FRA}} [[Marc Gomez]]
|{{bandiera|FRA}} [[Yves Beau]]
|{{bandiera|FRA}} [[Bernard Pineau]]
|-
|1982
|{{bandiera|FRA}} [[Serge Polloni]]
|{{bandiera|FRA}} [[Francis Perin]]
|{{bandiera|FRA}} [[Bruno Roussel]]
|-
|1983
|{{bandiera|FRA}} [[Marino Verardo]]
|{{bandiera|FRA}} [[Serge Polloni]]
|{{bandiera|CAN}} [[Dany Deslongchamp]]
|-
|1984
|{{bandiera|FRA}} [[Jean-Luc Gilbert]]
|{{bandiera|FRA}} [[Daniel Feudon]]
|{{bandiera|FRA}} [[René Bajan]]
|-
|1985
|{{bandiera|FRA}} [[Michel Dufour]]
|{{bandiera|FRA}} [[Charles Turlet]]
|{{bandiera|FRA}} [[Dominique Lardin]]
|-
|1986
|{{bandiera|FRA}} [[Jean-Pierre Cocquerelle]]
|{{bandiera|FRA}} [[Jean-Louis Auditeau]]
|{{bandiera|FRA}} [[Sylvain Le Goff]]
|-
|1987
|{{bandiera|FRA}} [[Patrick Jeremie]]
|{{bandiera|FRA}} [[Thierry Gault]]
|{{bandiera|FRA}} [[Claude Aigueparses]]
|-
|1988
|{{bandiera|FRA}} [[Michel Larpe]]
|{{bandiera|FRA}} [[André Becaas]]
|{{bandiera|FRA}} [[Gilles Guegan]]
|-
|1989
|{{bandiera|FRA}} [[Gérard Simonnot]]
|{{bandiera|FRA}} [[Christian Jany]]
|{{bandiera|FRA}} [[Thomas Davy]]
|-
|1990
|{{bandiera|FRA}} [[Thierry Dupuy]]
|{{bandiera|FRA}} [[Christophe Capelle]]
|{{bandiera|FRA}} [[Laurent Desbiens]]
|-
|1991
|{{bandiera|FRA}} [[Sylvain Bolay]]
|{{bandiera|FRA}} [[Thierry Bricaud]]
|{{bandiera|POL}} [[Zbigniew Ludwiniak]]
|-
|1992
|{{bandiera|POL}} [[Marek Swiniaski]]
|{{bandiera|FRA}} [[Xavier Vadrot]]
|{{bandiera|FRA}} [[Thierry Ferrer]]
|-
|1993
|{{bandiera|FRA}} [[Pascal Deramé]]
|{{bandiera|FRA}} [[Jean-François Anti]]
|{{bandiera|FRA}} [[Christophe Allin]]
|-
|1994
|{{bandiera|FRA}} [[Laurent Drouin]]
|{{bandiera|FRA}} [[Christophe Faudot]]
|{{bandiera|FRA}} [[Christian Guiberteau]]
|-
|1995
|{{bandiera|FRA}} [[Christophe Agnolutto]]
|{{bandiera|FRA}} [[Jean-Philippe Rouxel]]
|{{bandiera|FRA}} [[Jean-Philippe Duracka]]
|-
|1996
|{{bandiera|FRA}} [[Éric Drubay]]
|{{bandiera|FRA}} [[Jean-Philippe Duracka]]
|{{bandiera|FRA}} [[Christophe Faudot]]
|-
|1997
|{{bandiera|FRA}} [[Olivier Perraudeau]]
|{{bandiera|FRA}} [[Pierre Painaud]]
|{{bandiera|FRA}} [[Christopher Jenner]]
|-
|1998
|{{bandiera|FRA}} [[Dominique Péré]]
|{{bandiera|FRA}} [[Jean-Philippe Duracka]]
|{{bandiera|FRA}} [[Vincent Marchais]]
|-
|1999
|{{bandiera|FRA}} [[Frédéric Mainguenaud]]
|{{bandiera|FRA}} [[Éric Drubay]]
|{{bandiera|FRA}} [[Bruno Thibout]]
|-
|2000
|{{bandiera|FRA}} [[Eric Duteil]]
|{{bandiera|FRA}} [[Frédéric Delalande]]
|{{bandiera|FRA}} [[Jérôme Desjardins]]
|-
|2001
|{{bandiera|FRA}} [[Bertrand Guerry]]
|{{bandiera|FRA}} [[Christian Magimel]]
|{{bandiera|FRA}} [[Christophe Laurent]]
|-
|2002
|{{bandiera|EST}} [[Erki Pütsep]]
|{{bandiera|ITA}} [[Carlo Meneghetti]]
|{{bandiera|JPN}} [[Shinishi Fukushima]]
|-
|2003
|{{bandiera|FRA}} [[Alexandre Naulleau]]
|{{bandiera|FRA}} [[Christophe Diguet]]
|{{bandiera|FRA}} [[Sylvain Lavergne]]
|-
|2004
|{{bandiera|FRA}} [[Anthony Ravard]]
|{{bandiera|FRA}} [[Ludovic Auger]]
|{{bandiera|FRA}} [[Stéphane Barthe]]
|-
|[[Bordeaux-Saintes 2005|2005]]
|{{bandiera|SWE}} [[John Nilsson]]
|{{bandiera|FRA}} [[Denis Robin]]
|{{bandiera|FRA}} [[Jérôme Bonnace]]
|-
|2006
|{{bandiera|FRA}} [[Cédric Barre]]
|{{bandiera|FRA}} [[Mickael Larpe]]
|{{bandiera|EST}} [[Tarmo Raudsepp]]
|-
|2007
|{{bandiera|RUS}} [[Evgenij Sokolov]]
|{{bandiera|FRA}} [[Damien Gaudin]]
|{{bandiera|FRA}} [[Yoann Offredo]]
|-
|2008
|{{bandiera|LVA}} [[Gatis Smukulis]]
|{{bandiera|AUS}} [[David Tanner]]
|{{bandiera|FRA}} [[Yannick Marie]]
|-
|2009
|{{bandiera|FRA}} [[Yoann Bagot]]
|{{bandiera|FRA}} [[Jean-Lou Paiani]]
|{{bandiera|FRA}} [[Jérémie Dérangère]]
|-
|2010
|{{bandiera|FRA}} [[Adrien Petit]]
|{{bandiera|FRA}} [[Rudy Lesschaeve]]
|{{bandiera|FRA}} [[Etienne Pieret]]
|-
|2011
|{{bandiera|RUS}} [[Matvey Zubov]]
|{{bandiera|FRA}} [[Sylvain Déchereux]]
|{{bandiera|FRA}} [[Sylvain Blanquefort]]
|-
|2012
|{{bandiera|FRA}} [[Rudy Kowalski]]
|{{bandiera|EST}} [[Alo Jakin]]
|{{bandiera|FRA}} [[Johann Rigoulay]]
|-
|2013
|{{bandiera|FRA}} [[Yann Guyot]]
|{{bandiera|FRA}} [[Benoît Sinner]]
|{{bandiera|FRA}} [[Rudy Barbier]]
|-
|2014
|
|
|
|}
 
==Note==
La gestione delle situazioni anomale presenta diversi aspetti critici rispetto a considerazioni di [[qualità del software]]. Da una parte, sarebbe auspicabile che chi sviluppa un programma ponga una notevole cura nel prevedere tutte le possibili situazioni anomale che potrebbero insorgere durante l'esecuzione e nel predisporre le contromisure che il programma deve adottare in tali casi per ridurre al minimo le conseguenze di tali anomalie. La gestione "puntigliosa" di ''tutte'' le possibili situazioni anomale in ''tutti'' i possibili luoghi del codice in cui possono manifestarsi è infatti importante ai fini della [[robustezza (software)|robustezza]] e [[affidabilità (software)|affidabilità]] del software. D'altra parte, essendo le situazioni "anomale" potenzialmente molto numerose e diversificate, una gestione davvero completa potrebbe avere l'effetto indesiderabile di oscurare la struttura del [[codice sorgente]], poiché le (relativamente poche) [[istruzione (informatica)|istruzioni]] che il programma dovrebbe eseguire nel caso normale (o nei casi normali) si potrebbero trovare immerse (e "disperse") in mezzo a una quantità preponderante di istruzioni dedicate alla gestione di anomalie (magari molto improbabili), ovviamente a scapito della [[leggibilità (software)|leggibilità]] del programma stesso.
<references/>
 
==Collegamenti esterni==
==Segnalazione del fallimento di un metodo==
*{{cita web|http://www.bordeaux-saintes.fr/|Sito ufficiale|lingua=fr}}
Ogni [[metodo]] di un programma Java dovrebbe avere un ''compito'' ben preciso da portare a termine (descritto dal suo commento [[Javadoc]]). In presenza di anomalie o situazioni impreviste, è possibile che un metodo ''fallisca'', ovvero non sia in grado di portare a termine tale compito. Questa evenienza deve essere evidentemente segnalata al metodo [[chiamata di metodo|chiamante]] il quale poi potrà, a seconda dei casi, prendere qualche contromisura che gli consenta di concludere il ''proprio'' compito nonostante il fallimento del metodo chiamato, oppure, se questo è impossibile, dichiarare a sua volta il proprio fallimento nei confronti del proprio chiamante (e così via).
 
{{Portale|ciclismo|francia}}
Per segnalare il proprio fallimento, un metodo Java può ''sollevare'' (o "lanciare", per conservare il significato del corrispondente termine inglese ''to throw'') una eccezione. Si può considerare una eccezione sollevata da un metodo come analogo al concetto di ''valore restituito'' dal metodo. Tuttavia, Java distingue i due concetti, così che un metodo potrebbe per esempio tornare un valore intero ''oppure'' sollevare un'eccezione, che è un valore di altro tipo (in seguito vedremo quali sono i tipi ammissibili per i valori-eccezione). Il seguente estratto di codice mostra una situazione di questo genere:
 
[[Categoria:Bordeaux-Saintes]]
<source lang="java">
/**
* Calcola la differenza in giorni fra due date, specificate rispettivamente dal giorno
* "gg1", mese "mm1" e anno "aa1" e giorno "gg2", mese "mm2" e anno "aa2"
*/
public int differenzaDate(int gg1, int mm1, int aa1, int gg2, int mm2, int aa2)
throws DataNonValida
{
if(!dataValida(gg1, mm1, aa1) || !dataValida(gg2, mm2, aa2))
throw new DataNonValida();
else {
int risultato;
// ... calcola la differenza fra le date
return risultato;
}
}
</source>
 
Il metodo riportato ritorna, ''in assenza di errori'', un intero che rappresenta la distanza in giorni fra due date. Nel caso in cui una delle triple (giorno, mese, anno) non sia una data valida (per esempio, la tripla 31 2 2000), anziché ritornare un valore intero il metodo solleva una eccezione. La clausola <code>throws</code> nell'intestazione del metodo specifica che questo speciale valore di "eccezione" sarà di tipo ([[Classe (informatica)|classe]]) <code>DataNonValida</code>; il punto del codice in cui l'eccezione viene sollevata è l'[[istruzione]] <code>throw new DataNonValida()</code>. Ovviamente deve essere stata definita una classe <code>DataNonValida</code> e, come vedremo nel seguito, questa classe deve anche avere alcune caratteristiche specifiche che consentono l'utilizzo delle sue istanze come valori di eccezione.
 
La semantica dell'operatore <code>throw</code> ha alcuni aspetti in comune con quella dell'operatore <code>return</code>; in particolare, l'esecuzione dell'istruzione <code>throw</code> comporta la terminazione immediata del metodo e il passaggio del [[flusso di controllo|controllo]] (seppure secondo un particolare insieme di regole che si esamineranno nel seguito) al chiamante del metodo stesso.
 
==Gestione dell'eccezione nel chiamante==
Quando un metodo ne invoca un altro e quest'ultimo può sollevare un'eccezione (come specificato dalla clausola <code>throws</code> della sua intestazione), il chiamante ''può'' predisporsi per gestire tale evenienza. La gestione dell'eccezione avviene utilizzando una [[struttura di controllo]] specifica, detta ''blocco try-catch''. Come si vedrà, questa struttura di controllo ha un funzionamento in parte simile a (una forma ristretta di) [[Struttura di controllo#Goto|''goto'']] e in parte simile alla chiamata di un metodo.
 
Il seguente frammento di codice mostra l'uso del blocco try-catch nel chiamante:
 
<source lang="java">
public void faiQualcosa(Scanner input) {
boolean successo = false;
int g1, g2, m1, m2, a1, a2;
while (!successo) {
// chiede all'utente di inserire valori per g1, m1, a1, g2, m2, a2
try {
...
int dd = differenzaDate(g1, m1, a1, g2, m2, a2);
successo = true;
...
System.out.println("La differenza è " + dd);
} catch (DataNonValida dnv) {
System.out.println("Almeno una delle date inserite non è valida");
}
}
}
</source>
 
La clausola <code>try</code> controlla un [[blocco (programmazione)|blocco di codice]] all'interno del quale compare il metodo "a rischio" ''differenzaDate''. Quando il metodo viene eseguito, si danno due casi:
* il metodo ha successo e ritorna un intero. Il blocco controllato dal try viene portato a termine e il controllo passa alla prima istruzione successiva alla struttura di controllo try-catch. Quindi, ''successo'' diventa ''true'', viene stampata a video "La differenza è..." e il metodo termina;
* il metodo fallisce e solleva un'eccezione. Il blocco controllato dal try viene immediatamente terminato e il controllo passa al blocco controllato dalla clausola <code>catch</code>. Quindi, ''successo'' rimane ''false'', viene stampato il messaggio di errore ("Almeno una delle date inserite non è valida") e il controllo ritorna al [[ciclo while]].
 
In sostanza, il blocco try-catch consente di ''separare'' accuratamente il funzionamento del metodo nel caso "normale" (blocco try) e la gestione di situazioni anomale (blocco catch).
 
==La regola "handle or declare"==
Potrebbe darsi il caso in cui, a differenza di quanto visto nell'esempio precedente, il metodo chiamante ''non sia in grado'' di prendere contromisure rispetto al problema occorso. Supponiamo per esempio che il metodo che riceve dall'input i valori dei giorni, mesi e anni non sia ''faiQualcosa'' ma il ''suo chiamante'' (e che quindi, ''faiQualcosa'' riceva questi dati come argomenti). In tal caso è sensato supporre che sia opportuno delegare al chiamante di ''faiQualcosa'' anche la soluzione del problema (cioè chiedere nuovi dati all'utente). Il blocco di codice seguente mostra quale dovrebbe essere la forma del metodo ''faiQualcosa'' in questo caso:
 
<source lang="java">
public void faiQualcosa(int g1, int m1, int a1, int g2, int m2, int a2)
throws DataNonValida
{
int dd = differenzaDate(g1, m1, a1, g2, m2, a2);
System.out.println("La differenza è " + dd);
}
</source>
 
Poiché ''faiQualcosa'' non può risolvere il problema eventualmente segnalato da ''differenzaDate'', in questa versione esso non contiene una clausola try-catch. In questo caso, se ''differenzaDate'' solleva effettivamente l'eccezione, il modello di exception handling di Java prevede che anche ''faiQualcosa'' venga terminato. L'eccezione sollevata da ''differenzaDate'' sarà in tal caso ''automaticamente'' "propagata" al chiamante di ''faiQualcosa'', esattamente come se quest'ultimo avesse eseguito l'istruzione ''throw''. Per questo motivo, diventa ''obbligatorio'' inserire la clausola <code>throws DataNonValida</code> anche nell'intestazione di ''faiQualcosa'', segnalando così il fatto che anche questo metodo (indirettamente) può riportare una eccezione di tipo ''DataNonValida'' al proprio chiamante.
 
Questa regola di Java (innovativa rispetto all'exception handling del [[C++]]) viene detta regola ''handle or declare'' (''gestisci o dichiara''): a fronte di una possibile eccezione, un metodo deve gestirla ''oppure'' dichiarare a sua volta di sollevarla. Questo modello implica che una eccezione non possa mai passare ''inosservata''; se non la si gestisce, non si fa altro che rimandare al chiamante l'''obbligo'' di gestirla.
 
===Osservazioni===
Nei linguaggi sprovvisti di un meccanismo di exception handling, un metodo segnala il proprio fallimento, di norma, [[valore tornato (programmazione)|ritornando]] un valore speciale, a cui il programmatore attribuisce ''convenzionalmente'' il significato di segnalazione di fallimento. Per esempio, il metodo ''differenzaDate'' potrebbe tornare "-1" in caso di fallimento. Questo modello di gestione delle anomalie ha però diverse controindicazioni:
* la segnalazione segue una convenzione che deve essere documentata accuratamente; in assenza di una documentazione appropriata, il chiamante potrebbe non riuscire a interpretare il valore tornato;
* non sempre è possibile identificare un valore "speciale" da usare come segnalazione di errore; per esempio, se "differenzaDate" è pensato per fornire la differenza sia fra date crescenti che fra date decrescenti e distinguere i due casi, "-1" potrebbe essere un valore di ritorno lecito (per esempio il risultato di "differenzaDate(1, 1, 1970, 2, 1, 1970)");
* in ogni caso, non esiste alcun vincolo che ''imponga'' al chiamante di verificare correttamente se il metodo chiamato ha fallito e, nel caso, prendere provvedimenti. Rendendo obbligatoria la gestione delle eccezioni ("handle or declare") il modello di Java impedisce alle anomalie di passare "inosservate". Se questo comporta un onere per il programmatore (proprio perché lo obbliga a gestire ''ogni'' possibile anomalia), d'altra parte la regola contribuisce alla maggiore [[robustezza (software)|robustezza]] del programma.
 
==Eccezioni come oggetti==
Negli esempi precedenti, i valori usati come "eccezioni" erano istanze di una classe Java (''DataNonValida''). A differenza di quanto avviene in [[C++]], Java non ammette l'uso di [[tipo primitivo|tipi primitivi]] come valori-eccezione; le eccezioni, cioè, ''devono'' essere oggetti. Più in particolare, le classi definite per rappresentare le eccezioni devono estendere la classe <code>Throwable</code> (letteralmente: "che può essere lanciato"). A parte questo vincolo, la definizione di una classe di eccezione è libera. Molto spesso, in particolare, si usano [[attributo (programmazione)|attributi]] e [[metodo (programmazione)|metodi]] per corredare l'oggetto-eccezione di informazioni specifiche sul tipo di errore verificatosi.
 
Si consideri la seguente definizione:
 
<source lang="java">
public class DataNonValida extends Throwable {
private int g, m, a;
 
public DataNonValida(int g, int m, int a) {
this.g = g;
this.m = m;
this.a = a;
}
 
public int getGiorno() { return g; }
public int getMese() { return m; }
public int getAnno() { return a; }
}
</source>
 
Questa classe rappresenta una anomalia di data non valida; le sue istanze sono anche in grado di memorizzare nei propri attributi i valori di giorno, mese e anno di cui si è rilevata la non validità. Si consideri ora questa riscrittura del metodo ''differenzaDate'':
 
<source lang="java">
public int differenzaDate(int gg1, int mm1, int aa1, int gg2, int mm2, int aa2)
throws DataNonValida
{
if(!dataValida(gg1, mm1, aa1))
throw new DataNonValida(gg1, mm1, aa1);
else if(!dataValida(gg2, mm2, aa2))
throw new DataNonValida(gg2, mm2, aa2);
else {
int risultato;
// ... calcola la differenza fra le date
return risultato;
}
}
</source>
 
In questa variante, il metodo segnala l'anomalia occorsa generando un oggetto-eccezione che, a differenza dei casi precedenti, viene corredato dell'informazione aggiuntiva circa i valori di giorno, mese e anno che sono risultati scorretti. Questo potrebbe servire al chiamante, per esempio, per chiedere all'utente il reinserimento solo di una delle due date inserite (quella che si è rivelata scorretta).
 
Il seguente frammento di codice mostra come le informazioni inserite nell'oggetto-eccezione diventino disponibili a chi "cattura" (''catch'') l'eccezione stessa:
 
<source lang="java">
try {
int dd = differenzaDate(g1, m1, a1, g2, m2, a2);
...
} catch (DataNonValida dnv) {
System.out.println("La data " + dnv.getGiorno() + "/" + dnv.getMese() + "/" + dnv.getAnno() + " non è corretta");
}
</source>
 
L'identificatore <code>dnv</code> che compare nella clausola <code>catch</code> gioca un ruolo analogo a quello di un [[parametro (informatica)|parametro]] di un metodo. Esso cioè identifica un ''[[riferimento in Java|reference]]'' a cui viene assegnato l'oggetto-eccezione "lanciato" dall'istruzione <code>throw</code>. Tale oggetto può quindi essere manipolato come un oggetto qualsiasi, per esempio per estrarne informazione.
 
==Eccezioni e catch multiple==
Un metodo può sollevare più tipi di eccezione. Per esempio, un metodo che deve accedere a file potrebbe prevedere diverse segnalazioni di anomalie che rappresentano il fatto che il file non esista oppure che i suoi contenuti risultino danneggiati o scorretti:
 
<source lang="java">
public int leggiFile() throws FileInesistente, FileDanneggiato {
...
}
</source>
 
Analogamente, un blocco try-catch può comprendere più blocchi catch dedicati a gestire diversi tipi di eccezioni:
 
<source lang="java">
public faiQualcosa2() {
try {
leggiFile();
} catch (FileInesistente fi) {
System.out.println("Ooops! Il file " + fi.getNomeFile() + " non esiste!");
} catch (FileDanneggiato fd) {
System.out.println("Ooops! Il file " + fd.getNomeFile() + " contiene dati scorretti!");
}
}
</source>
 
==Eccezioni e polimorfismo==
Se le eccezioni sono descritte da classi che implementano ''Throwable'', è possibile che diverse classi-eccezione siano legate da relazioni di [[ereditarietà (informatica)|ereditarietà]]. In accordo con i principi generali del paradigma orientato agli oggetti, si avranno relazioni del genere fra classi che rappresentano rispettivamente tipi di eccezioni generali ([[Superclasse (informatica)|superclasse]]) e casi particolari ([[Sottoclasse (informatica)|sottoclassi]]). Per esempio, la classe ''FileInesistente'' e la classe ''FileDanneggiato'' potrebbero essere sottoclassi di una classe ''ProblemaAccessoAlFile'' (questa classe potrebbe per esempio definire il metodo ''getNomeFile'' usato negli esempi precedenti).
 
Il [[polimorfismo (informatica)|polimorfismo]] (legato alle relazioni di ereditarietà) gioca un ruolo importante nella gestione delle eccezioni in Java. Per esempio, una clausola ''catch'' il cui "parametro" sia dichiarato di tipo ''ProblemaAccessoAlFile'' potrebbe catturare tanto eccezioni di tipo ''FileInesistente'' quanto eccezioni di tipo ''FileDanneggiato'' (in analogia con l'applicazione del polimorfismo al passaggio parametri verso metodi e [[Costruttore (programmazione)|costruttori]]). Su considerazioni generali sul polimorfismo e il suo corretto uso, si veda la [[polimorfismo (informatica)|voce corrispondente]]. Nel caso estremo, un blocco ''catch'' con parametro di tipo ''Throwable'', per definizione, può catturare eccezioni di ''qualsiasi tipo''.
 
Per motivi analoghi, se un metodo dichiara di sollevare eccezioni di una certa classe ''C'', questo è assolutamente compatibile con l'eventualità che, sempre o in alcuni casi, tale metodo sollevi in effetti eccezioni di ''sottoclassi'' di ''C''.
 
Un altro legame fra polimorfismo ed eccezioni è dato dalle regole che governano l'[[overriding]] in Java. Quando si esegue overriding di un metodo che dichiara di sollevare eccezioni, il metodo ridefinito non può mai sollevare "più" tipi di eccezione di quelli sollevati dal chiamante. Se per esempio il metodo originale solleva eccezioni di classe ''C'', il metodo ridefinito potrebbe:
 
* dichiarare a sua volta di sollevare eccezioni di classe ''C'';
* dichiarare di sollevare eccezioni di una ''sottoclasse'' di ''C'';
* dichiarare di non sollevare eccezioni.
 
''Non'' potrebbe, invece:
 
* dichiarare di sollevare eccezioni di una superclasse di ''C'' o di una classe non legata a ''C'' da legami di ereditarietà.
 
Questa regola contribuisce a garantire che ''tutte'' le eccezioni vengano sempre gestite. Si consideri il seguente blocco di codice:
 
<source lang="java">
public class X {
public void faiQualcosa() throws C { ... }
}
 
public class Y {
public void m(X x) {
try {
x.faiQualcosa();
} catch (C c) {
...
}
}
}
</source>
 
In virtù del polimorfismo, sappiamo che il metodo ''m'' potrebbe essere invocato con un argomento che non è di classe X, ma di una sua sottoclasse qualsiasi. In virtù dell'''overriding'' e del [[binding dinamico]], quindi, non abbiamo garanzie che il metodo ''faiQualcosa'' chiamato in ''m'' sia ''esattamente'' quello definito nella classe X; esso potrebbe infatti essere stato ridefinito in qualche sottoclasse di X. A fronte di questa incertezza, però, le regole descritte sopra ci garantiscono che qualunque ridefinizione di ''faiQualcosa'' in qualunque classe non potrà sollevare eccezioni non gestite dalla ''catch'' del metodo ''m''; questo infatti si verificherebbe solo se tale ridefinizione sollevasse eccezioni che non sono né di classe ''C'' né di sue sottoclassi, ciò che appunto le regole riportate sopra escludono.
 
==Classificazione delle eccezioni==
Sebbene al programmatore sia consentito scrivere proprie classi di eccezione, Java dispone già di una propria gerarchia di classi-eccezione, di cui è rilevante conoscere la struttura generale.
 
Come si è detto, tutte le eccezioni sono ''Throwable''. Le due sottoclassi dirette di ''Throwable'' sono ''Error'' e ''Exception''. La classe ''Error'' dovrebbe essere riservata per situazioni anomale legate a ''malfunzionamenti della [[macchina virtuale Java]]''; in genere, queste ''non dovrebbero'' essere gestite, perché corrispondono a situazioni che per definizione si considerano ''irrecuperabili''. Se per esempio un programma entra in una condizione di [[stack overflow]], l'esecuzione di ''qualsiasi'' istruzione diventa inaffidabile; la terminazione del programma risulta quindi l'opzione più ragionevole.
 
Le ''Exception'' sono invece le eccezioni che possono essere gestite. La sottoclasse ''RuntimeException'' rappresenta quelle eccezioni che vengono sollevate dalla [[macchina virtuale Java]] (e quindi ''non'' da una istruzione ''throw'' del programma). Per esempio, il tentativo da parte del programma di usare un reference di valore [[null]] comporta la segnalazione di una ''RuntimeException'' da parte della JVM. Queste eccezioni ''possono'' essere catturate e gestite. Tuttavia, essendo in un certo senso eccezioni ''spontanee'' (non generate esplicitamente dal programma), esse non vengono dichiarate nelle clausole ''throws'' (in un certo senso, si assume che qualunque metodo possa incorrere in anomalie di questo genere, per cui dichiarare questa possibilità in modo sistematico, con il conseguente obbligo di gestione dato dalla regola [[handle or declare]], diverrebbe troppo oneroso).
 
==Voci correlate==
* [[Gestione delle eccezioni in C plus plus|Gestione delle eccezioni in C++]]
 
== Altri progetti ==
{{Interprogetto|b=Java/Gestione delle eccezioni}}
 
[[Categoria:Linguaggio Java]]