Non ho mai usato la clausola "getta" e oggi un amico mi ha detto che dovevo specificare nella dichiarazione del metodo che eccezioni che il metodo può lanciare. Tuttavia, ho usato eccezioni senza problemi senza farlo, quindi, perché è necessario se, in realtà, è necessario?Cosa succede se un metodo genera un'eccezione che non è stata specificata nella dichiarazione del metodo con "getta"
risposta
Java ha due diversi tipi di eccezioni: controllato Eccezioni e incontrollati eccezioni.
Le eccezioni non selezionate sono sottoclassi di RuntimeException
e non è necessario aggiungere una dichiarazione di proiezione. Tutte le altre eccezioni devono essere gestite nel corpo del metodo, con un'istruzione try/catch o con una dichiarazione di lanci.
Esempio di eccezioni non controllate: IllegalArgumentException
che viene talvolta utilizzato per la notifica, che è stato chiamato un metodo con argomenti non validi. Non servono tiri.
Esempio di eccezioni controllate: IOException
che alcuni metodi dal pacchetto java.io
possono generare. Utilizzare un try/catch o aggiungere throws IOException
alla dichiarazione del metodo e delegare la gestione delle eccezioni al chiamante del metodo.
"getta" helos delle parole chiave per delegare la gestione delle eccezioni ad altri componenti. Guarda la demo video: http://www.bitspedia.com/2013/11/how-to-delegate-exception-handling.html –
- È necessario dichiarare eccezioni controllate che il metodo genera.
- Se si dichiara "lancia Eccezione" che copre la maggior parte se non tutte le eccezioni controllate
- È sempre possibile generare un'eccezione di runtime non controllata e non è necessario dichiararla.
Sono abbastanza sicuro che se si tenta di generare un'eccezione controllata e non si è dichiarato che il metodo ha generato tale tipo, il codice non verrà nemmeno compilato (controllo ora).
EDIT, giusto quindi se si cerca qualcosa di semplice come
public static void main(String[] args) {
throw new Exception("bad");
}
si ottiene un errore di compilazione.
In particolare per la domanda, se si richiama un metodo dichiarato per generare le eccezioni, è necessario provare/recuperare il richiamo del metodo o dichiarare che il metodo genera le eccezioni.
Il problema era che non sapevo che c'erano eccezioni controllate e non controllate. Accetterei la tua risposta se non fosse perché Andreas_D mi ha dato la risposta perfetta. Grazie! – bluehallu
Se un metodo viene dichiarato con la parola chiave throws, qualsiasi altro metodo che desideri chiamare tale metodo deve essere pronto a prenderlo o dichiarare che esso stesso genererà un'eccezione.
Ad esempio se si desidera sospendere l'applicazione è necessario chiamare Thread.sleep(milliseconds);
Ma la dichiarazione per questo metodo dice che getterà una dichiarazione InterruptedException
:
public static void sleep(long millis) throws InterruptedException
Così se vuoi chiamarlo per esempio nel tuo metodo principale, devi prenderlo:
public static void main(String args[]) {
try {
Thread.sleep(1000);
} catch(InterruptedException ie) {
System.out.println("Opps!");
}
}
O fare il metodo dichiarano anche che sta gettando un'eccezione:
public static void main(String args[]) throws InterruptedException {
Thread.sleep(1000);
}
nel tuo ultimo esempio, come faccio a rilevare l'eccezione? –
@somefolk Nel mio ultimo esempio, il programma non catturerà l'opzione 'InterruptedException' perché il' throws' si trova sulla funzione 'main()'. Se si verifica una situazione, il programma terminerà bruscamente. – Anton
Può succedere, anche con controllato eccezioni. E a volte può interrompere la registrazione.
Supponiamo che un metodo di libreria usa questo trucco per consentire un'implementazione di Runnable
che può gettare IOException
:
class SneakyThrowTask implements Runnable {
public void run() {
throwSneakily(new IOException());
}
private static RuntimeException throwSneakily(Throwable ex) {
return unsafeCastAndRethrow(ex);
}
@SuppressWarnings("unchecked")
private static <X extends Throwable>X unsafeCastAndRethrow(Throwable ex) throws X {
throw (X) ex;
}
}
E si chiamano in questo modo:
public static void main(String[] args) {
try {
new SneakyThrowTask().run();
} catch (RuntimeException ex) {
LOGGER.log(ex);
}
}
L'eccezione non sarà mai registrato. E poiché si tratta di un'eccezione controllata, non è possibile scrivere questo:
public static void main(String[] args) {
try {
new SneakyThrowTask().run();
} catch (RuntimeException ex) {
LOGGER.log(ex);
} catch (IOException ex) {
LOGGER.log(ex); // Error: unreachable code
}
}
Ma scriverebbe mai un tale codice? Mi chiedo solo in quale situazione si potrebbe voler scrivere tale codice – Sameer
Sei obbligato solo a specificare le eccezioni controllate (e questo è davvero fastidioso). Quando non si riesce a farlo, il compilatore dovrebbe lamentarsi. –
Ho votato per lasciare aperta questa domanda perché e le risposte forniscono una buona copertura di ** throw ** con le eccezioni ** checked ** e ** unchecked **. – AdrianHHH