2011-02-03 7 views
19

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"

+0

Sei obbligato solo a specificare le eccezioni controllate (e questo è davvero fastidioso). Quando non si riesce a farlo, il compilatore dovrebbe lamentarsi. –

+0

Ho votato per lasciare aperta questa domanda perché e le risposte forniscono una buona copertura di ** throw ** con le eccezioni ** checked ** e ** unchecked **. – AdrianHHH

risposta

23

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.

+0

"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 –

4
  1. È necessario dichiarare eccezioni controllate che il metodo genera.
  2. Se si dichiara "lancia Eccezione" che copre la maggior parte se non tutte le eccezioni controllate
  3. È 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.

+0

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

13

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); 
} 
+0

nel tuo ultimo esempio, come faccio a rilevare l'eccezione? –

+0

@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

6

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 
    } 
} 
+0

Ma scriverebbe mai un tale codice? Mi chiedo solo in quale situazione si potrebbe voler scrivere tale codice – Sameer

Problemi correlati