Kotlin è un linguaggio di programmazione moderno che viene compilato in bytecode Java. È gratuito e open source e rende ancora più divertente la programmazione per Android.
Nell'articolo precedente, hai imparato di più sulla programmazione orientata agli oggetti scavando in classi astratte, interfacce, ereditarietà e tipi di alias in Kotlin.
In questo post continuerai a conoscere la programmazione in Kotlin imparando le eccezioni e come gestirle.
Le eccezioni vengono utilizzate per indicare un problema nel nostro codice durante l'esecuzione di un programma. La gestione delle eccezioni è la capacità di affrontare (o gestire) l'eccezione che potrebbe verificarsi. Se non gestiamo alcuna eccezione che si verifica, il nostro programma interromperà immediatamente l'esecuzione della nostra app.
La gestione delle eccezioni consente al nostro programma di continuare l'esecuzione anche in presenza di un'eccezione (sebbene sia altamente raccomandato registrare le eccezioni e segnalarle utilizzando uno strumento di segnalazione degli arresti anomali come Crashlytics).
In Java, abbiamo due tipi di eccezioni: selezionata e deselezionata. Li spiegherò brevemente entrambi, ma inizieremo con le eccezioni non controllate.
Queste sono eccezioni che vengono lanciate a causa di difetti nel codice. Sono una sottoclasse diretta o indiretta del RuntimeException
superclasse.
Esempi di eccezioni non controllate includono:
ArithmeticException
: lanciato quando dividi per zero.ArrayIndexOutOfBoundExceptions
: lanciato quando si accede a un array con un indice illegale. SecurityException
: lanciato dal responsabile della sicurezza per indicare una violazione della sicurezza.NullPointerException
: generato quando si richiama un metodo o una proprietà su un oggetto nullo.Un metodo che potrebbe generare un'eccezione non controllata non contiene alcuna informazione sull'eccezione generata nella dichiarazione del suo metodo.
public Integer divideByZero (numeratore intero, denominatore intero) numeratore / denominatore di ritorno; divideByZero (7, 0) // genera ArithmeticException
Questi tipi di eccezione possono essere prevenuti con la codifica corretta. Nel codice sopra, dovremmo controllare se il denominatore era zero prima di eseguire l'operazione. Per queste eccezioni, lo sviluppatore non ha bisogno di intercettare l'eccezione usando il prova a prendere
bloccare. In altre parole, non siamo costretti dal compilatore a racchiudere il codice che potrebbe attivare l'eccezione in a prova a prendere
bloccare. Invece, dovremmo semplicemente assicurarci che le eccezioni non si verifichino mai in primo luogo.
Inoltre, ricorda, Kotlin è un linguaggio sicuro. In altre parole, può aiutarci a evitare di ottenere NullPointerExceptions
nel nostro codice. Puoi leggere i post di Nullability, Loops e Conditions per ottenere un ripasso sulla sicurezza nulla in Kotlin.
Un metodo che potrebbe lanciare un'eccezione controllata deve dichiararlo nella sua firma del metodo usando getta
parola chiave. Se chiami un metodo che genera un'eccezione controllata, devi o lanciarlo di nuovo dalla tua funzione o prenderlo e gestirlo usando un prova a prendere
bloccare.
Le eccezioni controllate sono eccezioni che vengono verificate in fase di compilazione. Questi tipi di eccezioni ereditano dal Eccezione
classe. Un esempio di questo tipo di eccezione è IOException
. Ciò può verificarsi quando si tenta di accedere a un file che non può essere aperto perché non esiste. (FileNotFoundException
è una sottoclasse di IOException
.)
// esegue in un thread in background public void editFile (File file, String text) try file.getParentFile (). mkdirs (); FileOutputStream fileOutputStream = new FileOutputStream (file); Writer writer = new BufferedWriter (new OutputStreamWriter (fileOutputStream)); prova writer.write (testo); writer.flush (); fileOutputStream.getFD () sync ().; finally writer.close (); catch (IOException e) // Registra l'eccezione e.printStackTrace ();
Nel codice precedente, abbiamo usato a prova a prendere
blocco per gestire il IOException
dentro il editFile ()
metodo. Possiamo ora chiamare il editFile ()
metodo come normale, e il compilatore non si lamenterà.
editFile (new File (""), "my text");
Guardando il codice qui sotto, abbiamo refactored il metodo per utilizzare invece il getta
parola chiave nella firma del metodo. Questo indica ai chiamanti che devono gestire l'eccezione IOException
che potrebbe essere lanciato quando si chiama il metodo editFile ()
.
// questo dovrebbe essere in un thread in background public void editFile (File file, String text) genera IOException file.getParentFile (). mkdirs (); FileOutputStream fileOutputStream = new FileOutputStream (file); Writer writer = new BufferedWriter (new OutputStreamWriter (fileOutputStream)); prova writer.write (testo); writer.flush (); fileOutputStream.getFD () sync ().; finally writer.close ();
Per chiamare il metodo sopra, dobbiamo circondarlo in a prova a prendere
blocco per gestire l'eccezione.
prova editFile (new File (""), "my text"); catch (IOException e) e.printStackTrace ();
Questa è stata una breve panoramica delle eccezioni in Java. Vediamo ora come Kotlin gestisce le eccezioni.
La principale differenza tra i meccanismi di eccezione di Kotlin e Java è che tutte le eccezioni sono deselezionate in Kotlin. In altre parole, non sono dichiarati esplicitamente nelle firme delle funzioni, come in Java.
fun editFile (file: File, text: String) file.parentFile.mkdirs () val fileOutputStream = FileOutputStream (file) val writer = BufferedWriter (OutputStreamWriter (fileOutputStream)) prova writer.write (testo) writer.flush () fileOutputStream .fd.sync () finally writer.close ()
Qui, abbiamo convertito il editFile ()
metodo per una funzione di Kotlin. Puoi vedere che la funzione non ha il genera IOException
dichiarazione nella sua firma di funzione. getta
non è nemmeno una parola chiave in Kotlin.
Inoltre, possiamo chiamare questa funzione senza circondarla di prova a prendere
block-e il compilatore non si lamenterà. In altre parole, non esistono eccezioni controllate in Kotlin. Tutte le eccezioni sono deselezionate. (Si noti che se viene lanciata un'eccezione, l'esecuzione del programma si interromperà normalmente).
Se pensiamo che questa eccezione potrebbe sorgere, dovremmo comunque gestirla circondando il metodo con a prova a prendere
blocco - ma questo non è applicato dal compilatore Kotlin.
prova editFile (File (""), "testo 123") catch (e: IOException) e.printStackTrace ()
Se l'eccezione gettata all'interno del editFile ()
la funzione è un'istanza di IOException
classe, la nostra catturare
il blocco verrà eseguito e stamperemo semplicemente la traccia dello stack a scopo di debug.
prova a prendere
BloccareIl provare
costruire con catturare
e finalmente
le clausole in Kotlin sono simili a quelle di Java.
fun foo () try throw Exception ("Exception message") catch (e: Exception) println ("Exception handled") finally println ("all'interno di finally block")
Qui, stiamo lanciando un Eccezione
oggetto dentro il provare
bloccare. Si noti che non abbiamo incluso il nuovo
parola chiave come facciamo in Java per creare una nuova istanza. Si noti inoltre che non è stata specificata l'eccezione che verrà generata nella firma della funzione come dovremmo fare in Java.
Gestiamo tutte le sottoclassi e le classi di tipi Eccezione
nel blocco di cattura. L'opzionale finalmente
il blocco viene sempre eseguito; in questo caso, normalmente chiudiamo tutte le risorse o le connessioni precedentemente aperte in modo da evitare perdite di risorse. Ad esempio, se apri un file o crei un database o una connessione di rete in a provare
blocco, dovresti chiuderlo o liberarlo in a finalmente
bloccare.
Si noti che in Kotlin il gettare
costrutto è un'espressione e può combinarsi con altre espressioni.
val letter = 'c' val result = if (lettera in 'a' ... 'z') lettera else throw IllegalArgumentException ("Una lettera deve essere compresa tra dalla a alla z")
Anche il provare
il costrutto può essere usato come espressione.
fun foo (numero: Int) val result = try if (numero! = 1) throw IllegalArgumentException () true catch (e: IllegalArgumentException) false println (risultato) foo (2) // false
Qui, abbiamo assegnato il valore restituito da prova a prendere
bloccare al risultato
variabile. Se il numero non lo è 1
, getta un IllegalArgumentException
e il catturare
il blocco viene eseguito. Il falso
espressione nel catturare
il valore del blocco verrà assegnato al risultato
variabile. Se il numero è 1
invece, poi il vero
il valore dell'espressione verrà assegnato al risultato
variabile.
Le eccezioni in Kotlin si comportano normalmente in Java, ma voglio renderti conto di un'utile annotazione chiamata @throws
a Kotlin che potrebbe tornare utile. Poiché tutte le eccezioni in Kotlin sono deselezionate, gli sviluppatori che consumano il codice Kotlin da Java potrebbero non sapere che le tue funzioni generano eccezioni. Tuttavia, è comunque possibile aggiungere le possibili eccezioni che potrebbero essere generate con una firma del metodo con @Gettare
annotazione. Ciò avviserà i chiamanti Java di aver bisogno di gestire l'eccezione.
Vediamo un esempio pratico di questa annotazione.
/ * File Functions.kt * / fun addNumberToTwo (a: Any): Int if (a! Is Int) throw IllegalArgumentException ("Il numero deve essere un numero intero") return 2 + a
Qui, abbiamo definito una funzione di Kotlin che può generare un'eccezione IllegalArgumentException
solo se il tipo passato alla funzione non è di tipo Int
.
Chiamiamo questa funzione di alto livello addNumberToTwo ()
direttamente da Java nel modo seguente:
public void myJavaMethod () Intero risultato = FunctionsKt.addNumberToTwo (5); System.out.println (risultato); // 7
Questo funziona bene; il compilatore non si lamenta. Tuttavia, se vogliamo comunicare con i chiamanti Java che il addNumberToTwo ()
la funzione di primo livello genera un'eccezione, semplicemente aggiungiamo il @throws
annotazione alla firma della funzione.
@Throws (IllegalArgumentException :: class) fun addNumberToTwo (a: Any): Int if (a! Is Int) throw IllegalArgumentException ("Il numero deve essere un numero intero") return 2 + a
Questo @throws
l'annotazione può accettare un elenco separato da virgole di argomenti di classi di eccezioni. Nel codice sopra, abbiamo appena incluso una classe di eccezione-IllegalArgumentException
.
Ora dobbiamo aggiornare il nostro codice Java per gestire l'eccezione.
public void myJavaMethod () genera IllegalArgumentException Integer result = FunctionsKt.addNumberToTwo (5); System.out.println (risultato);
Se decompiliamo il Kotlin addNumberToTwo ()
funzione, usando il Mostra Kotlin Bytecode funzione (se sei in IntelliJ IDEA o Android Studio, usa Utensili > Kotlin > Mostra Kotlin Bytecode), vedremo il seguente codice Java:
// ... public static final int addNumberToTwo (@NotNull Object a) genera IllegalArgumentException Intrinsics.checkParameterIsNotNull (a, "a"); if (! (a instanceof Integer)) throw (Throwable) (new IllegalArgumentException ("Number deve essere un numero intero")); else return 2 + ((Number) a) .intValue (); // ...
Nel codice Java generato sopra (alcuni elementi del codice generato sono stati rimossi per brevità), puoi vedere che il compilatore ha aggiunto il getta
parola chiave alla firma del metodo, perché abbiamo incluso il @throws
annotazione.
In questo tutorial, hai imparato di più sulla programmazione in Kotlin esaminando le eccezioni. Abbiamo visto che Kotlin non ha verificato le eccezioni ma che, invece, tutte le eccezioni sono deselezionate. Abbiamo anche esaminato come gestire le eccezioni usando il prova a prendere
bloccare e ha visto l'utilità del @throws
annotazione in Kotlin per i chiamanti Java.
Per saperne di più sulla lingua di Kotlin, ti consiglio di visitare la documentazione di Kotlin. Oppure guarda alcuni dei nostri altri post di sviluppo di app per Android qui su Envato Tuts!