Kotlin de la zero Excepție de manipulare

Kotlin este un limbaj de programare modern care se compilează la Java bytecode. Este gratuit și open source, și face codificarea pentru Android chiar mai distractiv.  

În articolul precedent, ați învățat mai multe despre programarea orientată pe obiecte prin săparea în clase abstracte, interfețe, mosteniri și aliasuri de tip în Kotlin. 

În acest post, veți continua să învățați despre programarea în Kotlin, învățând despre excepții și cum să le rezolvați. 

1. Manipularea excepțiilor

Excepțiile sunt folosite pentru a indica o problemă în codul nostru în timpul executării unui program. Excepție de manipulare este capacitatea de a aborda (sau de a trata) excepția care ar putea să apară. Dacă nu rezolvăm nicio excepție care apare, programul nostru va înceta executarea bruscă a aplicației noastre imediat. 

Controlul excepțiilor permite programului nostru să continue executarea chiar dacă a existat o excepție (deși este foarte recomandat să vă înregistrați excepțiile și să le raportați utilizând un instrument de raportare a accidentelor, cum ar fi Crashlytics).   

În Java, avem două tipuri de excepții: verificate și neconfirmate. Voi explica pe scurt ambii, dar vom începe cu excepții necontrolate. 

Excepții necontrolate

Acestea sunt excepții care sunt aruncate din cauza defectelor din codul dvs. Ele sunt o subclasă directă sau indirectă a RuntimeException superclasei. 

Exemple de excepții necontrolate includ:

  • ArithmeticException: aruncate atunci când împărțiți cu zero.
  • ArrayIndexOutOfBoundExceptions: aruncat atunci când o matrice a fost accesată cu un index ilegal. 
  • SecurityException: aruncat de managerul de securitate pentru a indica o încălcare a securității.
  • NullPointerException: aruncat atunci când invocați o metodă sau o proprietate pe un obiect nul.

O metodă care ar putea arunca o excepție necontrolată nu conține nicio informație despre excepția aruncată în declarația sa de metodă. 

public Integer divideByZero (Numerator intreg, numitor de intreg) numarator / numitor retur;  divideByZero (7, 0) // aruncă ArithmeticException

Aceste tipuri de excepții pot fi prevenite prin codarea corectă. În codul de mai sus, ar fi trebuit să verificăm dacă numitorul era zero înainte de a efectua operația. Pentru aceste excepții, dezvoltatorul nu are nevoie să captureze excepția utilizând încearcă să prinzi bloc. Cu alte cuvinte, compilatorul nu este obligat să înfășoare codul care ar putea declanșa excepția într-un încearcă să prinzi bloc. În schimb, ar trebui să ne asigurăm că excepțiile nu apar niciodată în primul rând.

De asemenea, țineți minte, Kotlin este un limbaj sigur pentru null. Cu alte cuvinte, ne poate ajuta să evităm obținerea NullPointerExceptions în codul nostru. Puteți citi postul Nullabilitate, Loops și Condiții pentru a obține o rectificare a siguranței null în Kotlin. 

Excepții verificate în Java

O metodă care ar putea arunca o excepție verificată trebuie să declare astfel în semnătura sa folosind metoda aruncă cuvinte cheie. Dacă apelați o metodă care aruncă o excepție verificată, trebuie fie să o aruncați din nou din funcție, fie să o prindeți și să o gestionați utilizând încearcă să prinzi bloc. 

Excepțiile verificate sunt excepții care sunt verificate la momentul compilării. Aceste tipuri de excepții moștenesc de la Excepție clasă. Un exemplu de astfel de excepție este IOException. Acest lucru se poate întâmpla când încercați să accesați un fișier care nu poate fi deschis deoarece nu există. (FileNotFoundException este o subclasă de IOException.)

// efectua intr-un thread de fond public void editFile (Fisier fisier, text String) try file.getParentFile () .mkdirs (); FileOutputStream fileOutputStream = fișierul FileOutputStream (fișier) nou; Writer writer = BufferedWriter nou (noul OutputStreamWriter (fileOutputStream)); încercați writer.write (text); writer.flush (); fileOutputStream.getFD () sincronizare (.);  în cele din urmă writer.close ();  captură (IOException e) // Înregistrați excepția e.printStackTrace (); 

În codul precedent, am folosit a încearcă să prinzi bloc pentru a manipula IOException în interiorul editFile () metodă. Acum putem apela editFile () metoda normală, iar compilatorul nu se va plânge. 

editFile (fișier nou (""), "textul meu");

Privind la codul de mai jos, am refacturat metoda pentru a folosi în schimb aruncă cuvânt cheie în semnătura metodei. Acest lucru indică apelanților că trebuie să facă față excepției IOException care ar putea fi aruncat atunci când apelează metoda editFile ().

// aceasta ar trebui să fie într-un fir de fund public void editFile (Fișier de fișier, text de șir) aruncă IOException file.getParentFile () .mkdirs (); FileOutputStream fileOutputStream = fișierul FileOutputStream (fișier) nou; Writer writer = BufferedWriter nou (noul OutputStreamWriter (fileOutputStream)); încercați writer.write (text); writer.flush (); fileOutputStream.getFD () sincronizare (.);  în cele din urmă writer.close (); 

Pentru a apela metoda de mai sus, trebuie să o înconjurăm într-o încearcă să prinzi bloc pentru a face față excepției.

încercați editFile (fișier nou (""), "textul meu");  captură (IOException e) e.printStackTrace (); 

Aceasta a fost o scurtă privire la excepțiile din Java. Să vedem acum modul în care Kotlin se ocupă de excepții. 

2. Excepții la Kotlin

Principala diferență între mecanismele de excepție de la Kotlin și Java este că toate excepțiile sunt necontrolate în Kotlin. Cu alte cuvinte, ele nu sunt explicit declarate în semnăturile de funcții, așa cum sunt ele în Java.

Funcția FileReaderWriter (fileOutputStream)) încercați writer.write (text) writer.flush () fileOutputStream (file) .fd.sync () în cele din urmă writer.close ()

Aici am convertit editFile () la o funcție Kotlin. Puteți vedea că funcția nu are funcția aruncă IOException declarație în semnatura funcției sale. aruncă nu este nici măcar un cuvânt cheie în Kotlin. 

De asemenea, putem numi această funcție fără să o înconjurăm cu încearcă să prinzi bloc și compilatorul nu se va plânge. Cu alte cuvinte, nu există așa ceva ca excepții verificate în Kotlin. Toate excepțiile sunt necontrolate. (Rețineți că, dacă există o excepție aruncată, execuția programului se va opri în mod normal.) 

Dacă credem că această excepție ar putea apărea, ar trebui să o rezolvăm în continuare prin aceea că înconjoară metoda cu încearcă să prinzi bloc - dar acest lucru nu este impus de compilatorul Kotlin. 

încercați editFile (fișier (""), "text 123") captură (e: IOException) e.printStackTrace ()

Dacă excepția este aruncată în interior editFile () funcția este o instanță a IOException clasa noastră captură bloc va fi executat, și vom imprima pur și simplu traseu stivă pentru scopuri de depanare.

încearcă să prinzi bloc

încerca construi cu captură și in cele din urma clauzele din Kotlin sunt similare cu cele din Java. 

())        

Aici, aruncăm un Excepție obiect în interiorul încerca bloc. Observați că nu am inclus nou așa cum facem în Java pentru a crea un nou exemplu. De asemenea, observați că nu am specificat excepția care va fi aruncată în semnătura funcției așa cum ar trebui să avem în Java. 

Ne ocupăm de toate subclasele și clasele de tip Excepție în blocul de captură. Opțional in cele din urma blocul este întotdeauna executat - aici închidem de obicei orice resurse sau conexiuni care au fost deschise anterior pentru a preveni scurgerile de resurse. De exemplu, dacă deschideți un fișier sau creați o bază de date sau o conexiune de rețea într-o rețea încerca blocați, ar trebui să o închideți sau să o eliberați într - o in cele din urma bloc. 

Rețineți că la Kotlin arunca construct este o expresie și se poate combina cu alte expresii.

val letter = 'c' val rezultat = dacă (litera în 'a' ... 'z') altfel arunca IllegalArgumentException ("O literă trebuie să fie între a și z" 

De asemenea încerca construct poate fi folosit ca o expresie.

(f) false result = if (number! = 1) arunca IllegalArgumentException () true catch

Aici, am atribuit valoarea returnată de la încearcă să prinzi blocați la rezultat variabil. Dacă numărul nu este 1, aruncă o IllegalArgumentException si captură bloc este executat. fals expresie în captură valoarea blocului va fi atribuită rezultat variabil. Dacă numărul este 1 în schimb, atunci Adevărat valoarea de expresie va fi atribuită rezultat variabil.

Java Interop

Excepțiile de la Kotlin se comportă ca în Java în mod normal, dar vreau să vă dau seama de o adnotare utilă numită @Throws în Kotlin, care ar putea fi la îndemână. Deoarece toate excepțiile de la Kotlin sunt necontrolate, dezvoltatorii care vă consumă codul Kotlin din Java ar putea să nu știe că funcțiile dvs. aruncă excepții. Cu toate acestea, puteți adăuga eventualele excepții care ar putea fi aruncate la o semnătură de metodă cu @Arunca adnotare. Acest lucru va avertiza apelanții Java că trebuie să facă față excepției. 

Să vedem un exemplu practic al acestei adnotări.

/ * Functions.kt fișier * / distracție addNumberToTwo (a: Oricare): Int if (a! Este Int) aruncă IllegalArgumentException ("Numărul trebuie să fie un număr întreg") return 2 + a

Aici, am definit o funcție Kotlin care poate arunca o excepție IllegalArgumentException numai dacă tipul trecut la funcție nu este de tip Int

Noi numim această funcție de nivel superior addNumberToTwo () direct din Java în modul următor:

public void myJavaMethod () Integer rezultat = FuncțiiKt.addNumberToTwo (5); System.out.println (rezultat); // 7

Acest lucru funcționează bine; compilatorul nu se plânge. Cu toate acestea, dacă vrem să comunicăm cu apelanții Java că addNumberToTwo () funcția de nivel superior aruncă o excepție, pur și simplu adăugăm @Throws adnotare la semnătura funcției. 

@Throws (IllegalArgumentException :: clasă) distracție addNumberToTwo (a: Oricare): Int if (a! Este Int) aruncă IllegalArgumentException ("Numărul trebuie să fie un număr întreg"

Acest @Throws adnotarea poate accepta o listă de argumente ale clauzelor de excepție separate prin virgulă. În codul de mai sus, am inclus o singură clasă excepțională-IllegalArgumentException

Acum trebuie să ne actualizăm codul Java pentru a face față excepției.

public void myJavaMethod () aruncă IllegalArgumentException Integer result = FunctionsKt.addNumberToTwo (5); System.out.println (rezultat); 

Dacă decomprimăm Kotlin addNumberToTwo () funcția, folosind Afișați Bytecode Kotlin (dacă vă aflați în IntelliJ IDEA sau Android Studio, utilizați Unelte > Kotlin Afișați Bytecode Kotlin), vom vedea următorul cod Java:

// ... public static final int addNumberToTwo (@NotNull Obiect a) aruncă IllegalArgumentException Intrinsics.checkParameterIsNotNull (a, "a"); dacă (! (un exemplu de Integer)) throw (Throwable) (noul IllegalArgumentException ("Numărul trebuie să fie un număr întreg"));  altceva return 2 + ((Număr) a) .intValue ();  // ... 

În codul Java generat de mai sus (unele elemente ale codului generat au fost eliminate pentru dragul brevetului), puteți vedea că compilatorul a adăugat aruncă cuvinte cheie la semnătura metodei - pentru că am inclus @Throws adnotare. 

Concluzie

În acest tutorial, ați învățat mai multe despre programarea în Kotlin prin căutarea unor excepții. Am văzut că Kotlin nu a verificat excepțiile, dar că, în schimb, toate excepțiile sunt necontrolate. De asemenea, ne-am uitat la modul de gestionare a excepțiilor utilizând încearcă să prinzi bloc și a văzut utilitatea @Throws adnotare în Kotlin pentru apelanții Java. 

Pentru a afla mai multe despre limba Kotlin, vă recomand să vizitați documentația Kotlin. Sau verificați câteva dintre celelalte postări pentru dezvoltarea aplicațiilor Android aici pe Envato Tuts!


Cod