JavaRush /Java Blog /Random-IT /Eccezioni in Java
Roman
Livello 33

Eccezioni in Java

Pubblicato nel gruppo Random-IT
Quando mi sono imbattuto nell'argomento "Eccezioni", sono sorte molte domande alle quali ho dovuto cercare risposta in vari angoli di Internet per capire in dettaglio come funziona il tutto. Di conseguenza, ho compilato la mia spiegazione, che potrebbe essere più comprensibile per i principianti che hanno appena riscontrato questo fenomeno. Eccezioni in Java - 1Nei computer, un'interruzione è un segnale in ingresso al processore che indica che si sta verificando un evento che richiede una risposta immediata. Un segnale di interruzione richiede al processore di mettere in pausa un programma in esecuzione in modo che possa essere ripreso un po' più tardi, cioè il computer deve ricordare tutte le informazioni associate all'esecuzione del programma. Tali interruzioni sono temporanee, se non fatali. Tali interruzioni possono essere causate dal codice del programma o da alcune funzionalità hardware (ad esempio, la semplice pressione dei tasti sulla tastiera; i timer, ad esempio, per spegnere automaticamente il computer). Il numero di interrupt è limitato a un certo numero, integrato nella produzione di un particolare processore, ovvero per questo vengono assegnati speciali "canali" di comunicazione che consentono di accedere al processore bypassando tutti gli altri processi. Gli interrupt vengono generati automaticamente anche quando si verifica un errore nel codice del programma in esecuzione (ad esempio, se si verifica una divisione per zero). Tali interruzioni sono tradizionalmente chiamate trappole o eccezioni . In questi casi, è consuetudine dire: "È stata lanciata un'eccezione", ovvero è stata attivata un'eccezione o è stata lanciata un'eccezione (lanciata), ovvero una richiesta di interruzionecon la domanda “cosa fare?” inviato al processore. In questo momento il processore smette di funzionare, ricordando il punto in cui si è fermato, o meglio il cluster della cella successiva, le informazioni da cui devono essere eseguite. Viene ricordata l'intera catena di istruzioni eseguite e NON eseguite. Dopodiché, il processore legge le istruzioni dalla memoria per agire in caso di tale errore. Secondo questa istruzione, può inserire nuovi valori in determinati cluster, aggiungere alcune catene di azioni o un nuovo ciclo (ad esempio un ciclo di ritorno o di loop), ecc., Cioè, a seconda dell'errore precedentemente posto vengono eseguite le istruzioni down. Il sistema informatico stesso ha al suo interno molti interrupt automatici, che vengono attivati ​​dopo un certo periodo di tempo, ad esempio, per controllare i processi in esecuzione sul computer o eseguire allarmi impostati, raccogliere segnali esterni in entrata e vari convertitori di dati. Vale la pena ricordare che un gran numero di Interrupt, per una serie di motivi, può “bloccare” completamente il sistema. Un errore nel codice del programma causerà automaticamente un'interruzione del processore, che tenterà di elaborare secondo le istruzioni previste. Ma non tutti gli interrupt sono progettati per gestirli, oppure potrebbe produrre una procedura non adatta a noi, ad esempio semplicemente mandando in crash l'applicazione. Pertanto, nella programmazione, è possibile organizzare il proprio interrupt per una determinata sezione di codice in cui il programmatore vede potenzialmente la possibilità di un errore. In questo caso l'errore verrà elaborato all'interno del programma e non contatterà il processore per le istruzioni di elaborazione. La definizione di tali blocchi è organizzata creando un Oggetto “Eccezione” . Questo oggetto viene creato automaticamente nel blocco try-catch. Viene verificata la presenza di un errore nel blocco >trye, se presente, il programma va al blocco catch, dove vengono intraprese azioni per prevenire o livellare l'errore. Ad esempio, se inseriamo dalla tastiera Numeri , che successivamente dovranno essere sommati e sottratti, allora inserendo Lettere da tastiera non sarà possibile sommarli con Numeri (denotiamo la somma di queste due variabili con la lettera S). Pertanto, come squadra, trydobbiamo verificare se il numero A, contenente Numeri, può essere sommato al numero B, contenente Lettere (cioè S = A + B), e se questo non è possibile, ed è impossibile, allora certi È necessario adottare misure affinché NON si verifichino errori e non arrivi al processore un nuovo interrupt con la domanda "cosa fare?". Se non è presente alcuna eccezione nel programma, la sua esecuzione verrà interrotta dal processore. Se c'è un'Eccezione, quando viene “catturata” dal comando try, il controllo passa al comando catch, che può impostare una soluzione alternativa, ad esempio, non aggiungeremo questi due numeri, ma imposteremo S = A.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 } catch (Exception igogo1) {
   S = a;
 }
 return S;
/* stringa “int r = 1;” non viene eseguito perché si è verificato un errore e il programma reindirizza il lavoro direttamente al gestore delle eccezioni (catch block*/ Pertanto, la presenza di Eccezioni è un'opportunità per risolvere il problema all'interno del programma senza lanciarlo a livello del processore. L'oggetto “Eccezione”, che viene creato automaticamente nel blocco tryquando viene rilevato un errore, contiene il valore del tipo di errore. Chiamiamolo "OurException" - per il nostro caso specifico con una descrizione del nostro errore specifico. I creatori del linguaggio Java hanno creato in anticipo un certo elenco di errori tipici e opzioni tipiche per correggerli, cioè in Java c'è una certa libreria di Eccezioni , a cui possiamo rivolgerci per gestire un errore che si è verificato, così come non scrivere noi stessi il codice di elaborazione e quindi OurException è molto probabilmente già stata descritta da qualcuno, quindi dobbiamo solo sapere il nome di quale di queste eccezioni inserire nel nostro programma per gestire il codice dove potrebbe verificarsi un errore. Se commettiamo un errore e selezioniamo un'eccezione errata dalla libreria , allora il gestore non la “catturarà”, l'errore non troverà una soluzione all'interno del programma e la richiesta verrà inviata al processore. Ma c'è un modo per i pigri. Se non conosciamo dalla libreria il nome dell'eccezione di cui abbiamo bisogno, allora possiamo prendere quella generale con il nome “ Exception ”, come nell'esempio sopra descritto. Questa eccezione è in grado di gestire qualsiasi tipo di errore, ma non è in grado di fornire informazioni specifiche sull'incidente che potremmo registrare. La libreria di Eccezioni scritte in precedenza è composta da Eccezioni controllate e non controllate . Quelli controllabili sono quelli che possono essere corretti senza interrompere il lavoro del programma, cioè se proviamo ad aprire un file in una cartella in cui non esiste, il sistema ce lo farà sapere, possiamo rilasciare il file nella cartella desiderata e continuare il programma. Cioè, infatti, è stata inviata una richiesta di Interrupt al processore , ma senza la domanda: "cercare cosa fare per questo problema?!?!" Abbiamo inviato un Interrupt, che noi stessi abbiamo rilevato, con un'istruzione già pronta, che il processore ha elaborato e ha continuato l'esecuzione del programma. Non vengono selezionati quegli errori che non possono essere corretti e il programma verrà chiuso prima del completamento, ovvero verrà inviata una richiesta di interruzione al processore, che in ogni caso interromperà l'esecuzione del programma. L'unico scopo di scrivere tali eccezioni nel programma è far capire all'utente cosa è successo, poiché, una volta rilevata questa interruzione, possiamo visualizzare sullo schermo un messaggio informativo a causa del quale il programma si è bloccato. Il secondo motivo per rilevare tali interruzioni è la possibilità di registrarle nei log per analisi successive (sei stato violato, ma almeno sai dove). Una conseguenza della presenza di tali biblioteche è la necessità di ricordarsi di includerle. (Un elenco di eccezioni selezionate e non selezionate con librerie può essere trovato, ad esempio, qui ) Se non sappiamo esattamente quale libreria includere o ci sono diverse opzioni di errore, possiamo catchelencare le eccezioni richieste in diverse. Il sistema stesso selezionerà il gestore corretto se è nell'elenco. Invece di un'eccezione specifica, puoi scrivere una " Eccezione " generale in grado di gestire qualsiasi tipo di eccezione se non è stata elaborata nei blocchi precedenti.
int a = 4;
String b = “hello”;
int S = 0;
 try {
   S = a + b;
   int r = 1;
 }
catch(NullPointerException blabla2) {
   System.out.println("Exception handling code for the NullPointerException.");
 }
catch (ArithmeticException ex1) {
   S = a;
 }
catch(Exception uups1) {
   System.out.println("Exception occured");
 }
 return S;
Se è presente un blocco, tryviene creata automaticamente un'eccezione. Se ad un certo punto è necessario forzare un'eccezione , viene utilizzato il comando throw. Cioè, creiamo autonomamente un oggetto new throw... dopodiché il programma interrompe il suo lavoro, invia una richiesta di Interrupt al processore e viene trasferito alla sezione del programma catch, da dove cerca di ottenere istruzioni per ulteriori azioni. Creando manualmente un'Exception , possiamo specificarne il tipo specifico dalla libreria:

throw new ArithmeticException("Access denied - You must be at least 18 years old.");
quindi il gestore cercherà un blocco catchcon questa particolare eccezione : ricerca in tutto il programma, su tutti i lati catch. Dopo il throwcomando di gestione delle eccezioni, tutto il codice di programma rimanente NON verrà eseguito, ad eccezione di quello che si trova nel blocco catch. Se il gestore non viene trovato nel programma, al processore viene posta la domanda: “decidi tu stesso cosa fare” e interrompe il programma. La chiamata new throw... può essere effettuata sia all'interno >tryche all'esterno del blocco (in qualsiasi punto del programma)
try {
   /* функция or действие, в котором есть сомнения. То есть: «попробуй выполнить это, а если не получится, а, если не получится, запускай режим исключения» */
   throw new CallForException(); /* Назначаем исключение, которое будет работать в случае наличия ошибки в функции, описанной выше. Здесь исключение «CallForException» - берется из библиотеки существующих исключений */
} catch (CallForException ee1) {
   /* Корректируем ошибку, чтобы программа не «отвалилась» or выводим сообщение об ошибке or что-то ещё */
} finally {
   /* этот блок работает всегда независимо от того была ошибка or нет. А если была, то сработало ли решение в catch or нет */
   /* часто используется для подчистки хвостов, например, для закрытия запущенного file or базы данных */
   /* в ряде случаев блок catch вообще может быть опущен и оставлен только блок finally и наоборот finally может быть опущен и оставлен только catch */
   /* Не допускается использование этого блока в ряде случаев, например, когда функция System.exit() запущена or другие системные Исключения, типа «отключение электроэнергии» и т.п. */
}

Notifica delle eccezioni

I metodi scritti in precedenza da qualcuno possono includere il lancio di eccezioni. Per sicurezza, il programmatore che ha scritto il codice ha avvertito i programmatori successivi che potrebbe verificarsi un errore nel metodo da lui scritto. Quindi, ad esempio, il metodo di creazione del file descritto di seguito stabilisce che durante la creazione di un file potrebbe verificarsi un errore (non esiste alcun file nel percorso specificato), il che significa che sarà necessario un gestore di errori:
public void createFile(String path, String text) throws IOException {
    FileWriter writer = new FileWriter(path, true);
    writer.write(text);
    writer.close();
}
Ma allo stesso tempo non esiste un gestore stesso, il che significa che ora non possiamo semplicemente chiamare il metodo scritto nel nostro programma in modalità normale. Ora dobbiamo scrivere un gestore di errori e chiamare questo metodo nel blocco try:
String filePath = "hello.txt";
String text = "Hello World";

try {
    createFile(filePath, text);
} catch (IOException ex) {
    System.err.println("Error creating file: " + ex);
}

Eccezioni native

È possibile scrivere le proprie eccezioni per gestire determinati errori se le librerie esistenti non sono sufficienti per noi. Per fare ciò, creiamo semplicemente una classe che eredita dalla classe Exception
public class StudentNotFoundException extends Exception {

    public StudentNotFoundException (String message) {
        super(message);
    }
}
Ci sono due regole da tenere a mente quando crei le tue eccezioni:
  1. Il nome della nostra classe deve terminare con "Eccezione"
  2. La classe deve contenere un costruttore con una variabile stringa che descrive i dettagli del problema dell'eccezione. Nel costruttore viene chiamato il super costruttore e viene passato un messaggio.
Un esempio di utilizzo dell'eccezione generata:
public class StudentManager {
    public Student find(String studentID) throws StudentNotFoundException {
        if (studentID.equals("123456")) {
            return new Student();
        } else {
            throw new StudentNotFoundException(
                "Could not find student with ID " + studentID);
        }
    }
}
Catturiamo questa eccezione con il codice:
public class StudentTest {
    public static void main(String[] args) {
        StudentManager manager = new StudentManager();
         try {
            Student student = manager.find("0000001");
        } catch (StudentNotFoundException ex) {
            System.err.print(ex);
        }
    }
}
Il risultato dell'esecuzione del programma sarà: StudentNotFoundException: Impossibile trovare lo studente con ID 0000001

Perché è necessario scrivere Eccezioni?

Nel 1996, il razzo Ariane 5 si schiantò a causa di un'errata conversione di una variabile float in una variabile intera. Non c'erano eccezioni o gestori per questa situazione. Se durante il download di un file si verifica un'interruzione della connessione a Internet, la presenza di un'Eccezione consentirà di continuare il download dopo il ripristino della connessione. Se non è presente alcuna eccezione, il download dovrà ricominciare da capo.

Riferimenti:

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION