DOMANDA Eccezioni java

Androidiano93

Utente Attivo
287
1
CPU
i5 3570k
Scheda Madre
Asus P8Z77-V LE PLUS
HDD
Ssd Samsung pro series 840 - Seagate Barracuda 1TB 7200rpm 64MB cache
RAM
Corsair Vengeance Blue 2X4GB CL9 1600MHz
GPU
Gigabyte nvidia GTX 670 OC 4GB
Monitor
Asus VE247H
PSU
Antec HCG-620m
Case
Thermaltake Armor Revo Nero
OS
Win7 x64
Salve a tutti, dal corso di programmazione orientata agli oggetti ho capito tutto finora, tranne qualcosa riguardante le eccezioni, mi spiego meglio:
abbiamo visto che le classi di eccezioni possono appartenere a o ereditare da Exception o RuntimeException... le prime sono un po' più "pesanti" e richiedono controlli obbligatori, mentre per le seconde basterebbe un if, ma è qui che mi confondo: throw e throws quando e dove vanno messi? E il try catch, quando e dove? solo nei main solitamente, vero? Gradirei che qualcuno mi spiegasse per entrambi i tipi di eccezioni come e con che logica vanno sistemati throw, throws, try, catch, quando sono obbligatori, quando consigliati, etc. Grazie! :)
 

wolf1792

Utente Attivo
324
53
CPU
Intel i5 2320
Scheda Madre
AsRock P67 Pro3
HDD
WD caviar blue 500Gb
RAM
8 Gb Vegeance low profile
GPU
ATI HD6850
Monitor
Tv Samsung 24" Full-HD
PSU
XFX 450W
Case
Cooler Master 330
OS
windows 8/Ubuntu 13.04
allora, genericamente con le eccezioni gestisci i possibili errori che potrebbero avvenire durante l'esecuzione..
throws si mette nella dichiarazione di un metodo che potrebbe lanciare eccezioni..
throw lancia un eccezione..
-quindi ogni metodo che contiene un throw dovrà specificare la clausola throws..

try e catch invece servono al livello superiore per gestire le eccezioni lanciate..
supponi di avere
void metodo2 throws QualcheEccezione(){}

quando tu chiami metodo due dovrai chiamarlo all'interno di un blocco try..
quindi try{
metodo2();
}

alla fine del blocco try ci saranno 0 o più blocchi catch per le eccezioni che il blocco try poteva catturare...
 
  • Mi piace
Reazioni: Androidiano93

Androidiano93

Utente Attivo
287
1
CPU
i5 3570k
Scheda Madre
Asus P8Z77-V LE PLUS
HDD
Ssd Samsung pro series 840 - Seagate Barracuda 1TB 7200rpm 64MB cache
RAM
Corsair Vengeance Blue 2X4GB CL9 1600MHz
GPU
Gigabyte nvidia GTX 670 OC 4GB
Monitor
Asus VE247H
PSU
Antec HCG-620m
Case
Thermaltake Armor Revo Nero
OS
Win7 x64
Mmm grazie ma ancora non mi è chiara qualcosa: il nostro professore ha fatto tempo fa una classe Razionale per i numeri razionali dove nel cotruttore c'è if(parametro_denominatore)==0 throw new IllegalArgumentException; ma nell'intestazione del metodo non c'è nessun throws! Quali sono quindi le funzioni, gli obblighi e le utilità di throw e throws rispetto ai due tipi di eccezioni?
 

Skills07

Head of Development
Staff Forum
Utente Èlite
35,437
11,501
CPU
Ryzen 7 5800x
Dissipatore
Deepcool gammax l240 v2
Scheda Madre
Aourus Gigabyte X-470 ultra gaming
HDD
Samsung Evo 850 250gb ,2tb x 2 toshiba P300, 256 Ssd silicon power, Samsung evo plus 1tb nvme
RAM
32 gb G.Skill Tridentz 3200 mhz RGB
GPU
Zotac - RTX 3070 Ti Trinity OC
Monitor
ASUS TUF QHD 165hz IPS, ITEK GCF 165hz IPS QHD, Samsung Curvo 144hz QHD
PSU
Seasonic Focus 650w 80 platinum
Case
Coolermaster h500p
Periferiche
Asus Tuf Wireless
Net
Fibra Tim 100mb
OS
Windows 10 Pro 64 bit
allora per le eccezioni funziona cosi in Java:

ad esempio sai che un metodo tipo ora invento somma numeri lancia una Eccezione numerica:
in primis crei l'eccezione

Public class EccezioneNumerica extends Exception{
String msg =System.out.println("eccezione numerica");
super(msg);
}

cosi hai creato un eccezione personalizzata che estende exception.

poi che ne so hai un metodo somma che lancia una EccezioneNumerica e avrai cosi

public int Somma(int a, int b) throws EccezioneNumerica

e il try catch invece lo metti nel codice per intercettare dove avviene l'eccezione

spero di essere stato esaustivo
 

1nd33d

Utente Attivo
653
279
CPU
Intel i5 3570K @ 4,5Ghz
Dissipatore
Scythe Mugen 2
Scheda Madre
Gigabyte Z77X-UD3H
HDD
Samsung 840 PRO 256GB + Sandisk Ultra 250GB + Sandisk Plus 960GB
RAM
2x8GB Crucial Ballistix Tactical @2000Mhz CL9
GPU
XFX RX480 GTR Black Edition
Audio
Auzentech X-Fi Forte
Monitor
AOC i2369VW
PSU
Seasonic P660
Case
eh?
Periferiche
Razer Naga HEX v2
OS
Windows 10 64bit - Linux Mint 18
Devi aver chiaro il funzionamento delle eccezioni e la loro gestione.
Il "lancio" (in altri linguaggi detto anche "sollevamento") dell'eccezione avviene quando si raggiunge uno stato di inconsistenza o di errore che potrebbe non permettere la prosecuzione del programma (ci sono programmatori che usano eccezioni con molta più disinvoltura, non è in generale una buona pratica abusarne...).
L'eccezione una volta lanciata risale i contesti (lo stack di chiamate) fino a quando non trova un blocco try/catch che la gestisce.
L'eccezione viene sempre lanciata con un throw, che può essere scritto da te (per le tue eccezioni personalizzate) o avvenire nelle librerie Java, o in alcuni casi essere generata da una operazione non valida, per esempio la divisione per zero. L'eccezione una votla lanciata interrompe l'esecuzione del codice e risale i contesti fino a trovarsi in un blocco try/catch con un catch che soddisfi ("match") il tipo di eccezione.
Ora, se una operazione o una chiamata a un metodo può lanciare una eccezione, la chiamata a tale metodo deve essere racchiusa in un try/catch adatto, altrimenti il metodo da cui chiami deve contenere in firma la clausola throws, che dirà al metodo ancora più a monte che c'è una eccezione che potrà uscire da quel contesto.
E' un concetto molto semplice che si capisce ragionando per induzione su un caso base:
Codice:
void metodoA() throws MyExc{
   throw new MyExc();
}

void metodoB(){
   try{
      metodoA();
   }catch(MyExc e){
      //fai qualcosa
   }
   //resto di B
}

void metodoC(){
   metodoB();
   //resto di C
}
In questo caso A lancia una eccezione, è il metodo B che chiama A e la chiamata è racchiusa in un blocco try/catch che fa match. L'eccezione viene catturata e non si propaga mai al metodo C, che quindi può ignorarla. SI noti che in questo caso il codice dal punto "//resto di B" viene eseguito.

Se invece non ci fosse il try/catch in metB:
Codice:
void metodoA() throws MyExc{
   throw new MyExc();
}

void metodoB() [COLOR=#00ff00]throws MyExc[/COLOR]{   
   metodoA();
   //resto di B
}

void metodoC(){
   try{   
      metodoB();
   }catch(MyExc){
      //fai qualcosa
   }
   //resto di C
}
In questo caso, B non gestisce l'eccezione, e ne lascia l'onere ai contesti chiamanti (nel nostro caso metodoC). In metodoC c'è il try/catch giusto che gestisce l'eccezione MyExc lanciata da A e transitata per B.
In questo caso l'eccezione viene gestita a un livello superiore rispetto a B per cui il codice al punto "//resto di B" non viene eseguito! Si noti che in questo caso, se B non gestisce l'eccezione, chi chiama B deve saperlo, per questo in firma a B si deve aggiungere il throws che dice "questo metodo può sollevare l'eccezione MyExc". Nota come a C non interessa se è stato B o A a lanciare l'eccezione, gli interessa solo sapere che chiamando metodoB, potrebbe arrivargli una eccezione generata in uno dei contesti inferiori. Infatti la clausola "throws" in firma ai metodi non distingue il metodo che contiene l'effettivo lancio dell'eccezione da quelli che si limitano a propagarla.
E se nemmeno C volesse gestire MyExc con un try/catch? Allora anche C in firma avrà "throws MyExc" e sarà chi chiama C che dovrà gestire la situazione.

ps: non l'ho evidenziato nel codice, ma se ci sono altre istruzioni dentro al blocco try successive all'istruzione che alza o propaga l'eccezione, queste non vengono eseguite. Tipicamente si usa aggiungere il blocco finally dopo al catch per inserire quelle istruzioni che devono essere eseguite sia che ci sia una eccezione, sia che non ci sia. A un primo sguardo sembra che il blocco finally sia inutile, per esempio, dopo il catch nel metodo C, perchè sappiamo che "//resto di C" viene eseguito.
In realtà il finally ha un senso più astratto, tipicamente racchiude quelle istruzioni che noi vogliamo avere la certezza che vengano eseguite (per esempio chiudere stream o liberare altre risorse) perchè anche il "//resto di C" potrebbe sollevare eccezioni, e magari non controllate in C.
In Java7 mi pare abbiano aggiunto un costrutto simile al try (chiamato "try with resource") che permette di fare qualcosa di simile senza l'uso del finally.

ps2: parlavi di diversi tipi di eccezioni, una eccezione è un oggetto e quindi ha una sua classe che lo definisce. Le classi di eccezioni possono essere estese come le altre classi, per cui puoi avere diversi tipi di eccezione. Questo è importante da capire perchè quando inserisci il nome dell'eccezione in un catch, quel catch "matcherà" tutte le eccezioni di quel tipo e dei tipi sottotipo di quello indicato.
Se per esempio faccio un catch(Exception e), questo catch cattura tutte le eccezioni, perchè tutte sono sottoclasse di Exception.
 
Ultima modifica:

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!