Kotlin er et moderne programmeringsspråk som kompilerer til Java bytecode. Det er gratis og åpen kildekode, og gjør koding for Android enda morsommere.
I forrige artikkel lærte du mer om objektorientert programmering ved å grave inn abstrakte klasser, grensesnitt, arv og type aliaser i Kotlin.
I dette innlegget fortsetter du å lære om programmering i Kotlin ved å lære om unntak og hvordan du håndterer dem.
Unntak brukes til å indikere et problem i vår kode under et programs utførelse. Unntakshåndtering er evnen til å adressere (eller håndtere) unntaket som kan oppstå. Hvis vi ikke håndterer noe unntak som oppstår, stopper programmet vårt med å plukke opp appen umiddelbart, og krasjer vår app umiddelbart.
Unntakshåndtering gjør at programmet vårt kan fortsette å utføre selv om det var unntak (selv om det anbefales å logge unntakene dine og rapportere dem ved hjelp av et krasjrapporteringsverktøy som Crashlytics).
I Java har vi to typer unntak: merket og ukontrollert. Jeg forklarer dem begge kort, men vi starter med ukontrollerte unntak.
Dette er unntak som kastes på grunn av feil i koden din. De er en direkte eller indirekte underklasse av RuntimeException
super.
Eksempler på ukontrollerte unntak inkluderer:
ArithmeticException
: kastet når du deler med null.ArrayIndexOutOfBoundExceptions
: kastet når en matrise har blitt åpnet med en ulovlig indeks. SecurityException
: kastet av sikkerhetsansvarlig for å angi et sikkerhetsbrudd.NullPointerException
: kastet når man påberoper en metode eller egenskap på et null objekt.En metode som kan kaste et ukontrollert unntak inneholder ingen informasjon om unntaket som er kastet på metodedeklarasjonen.
offentlig Integer divideByZero (Integer teller, Integer nevner) retur teller / nevner; divideByZero (7, 0) // kaster ArithmeticException
Disse typer unntak kan forhindres ved å kode riktig. I koden ovenfor bør vi ha sjekket om nevneren var null før operasjonen ble utført. For disse unntakene trenger utvikleren ikke å ta unntaket ved hjelp av prøv ... fange
blokkere. Med andre ord, vi er ikke tvunget av kompilatoren til å pakke inn koden som kan utløse unntaket i a prøv ... fange
blokkere. I stedet bør vi bare sørge for at unntakene aldri skjer i utgangspunktet.
Husk også, Kotlin er et null sikkert språk. Med andre ord kan det hjelpe oss med å unngå å få NullPointerExceptions
i vår kode. Du kan lese Nullability, Loops og Conditions posten for å få en oppdatering på null sikkerhet i Kotlin.
En metode som kan kaste et kontrollert unntak, må deklareres i sin metode underskrift ved hjelp av kaster
søkeord. Hvis du ringer en metode som kaster et kontrollert unntak, må du enten kaste den igjen fra funksjonen din eller for å fange den og håndtere den ved hjelp av en prøv ... fange
blokkere.
Sjekket unntak er unntak som blir sjekket på kompileringstidspunktet. Disse typer unntak arver fra Unntak
klasse. Et eksempel på denne typen unntak er IOException
. Dette kan oppstå når du prøver å få tilgang til en fil som ikke kan åpnes fordi den ikke eksisterer. (FileNotFoundException
er en underklasse av IOException
.)
// utføre i en bakgrunnstråd public void editFile (Fil fil, String text) prøv file.getParentFile (). mkdirs (); FileOutputStream fileOutputStream = ny FileOutputStream (fil); Skribentforfatter = Ny BufferedWriter (Ny OutputStreamWriter (FileOutputStream)); prøv writer.write (text); writer.flush (); fileOutputStream.getFD () synk (.); endelig writer.close (); fangst (IOException e) // Log unntaket e.printStackTrace ();
I den forrige koden brukte vi en prøv ... fange
blokk for å håndtere IOException
inne i editFile ()
metode. Vi kan nå ringe editFile ()
Metoden som vanlig, og kompilatoren vil ikke klage.
editFile (ny fil (""), "min tekst");
Vi ser på koden nedenfor, og har refactored metoden til å isteden bruke kaster
søkeord i metoden signatur. Dette indikerer at innringere som de trenger for å håndtere unntaket IOException
Det kan bli kastet når man ringer metoden editFile ()
.
// dette burde være i en bakgrunnsrute offentlig tomgang editFile (Fil fil, String text) kaster IOException file.getParentFile (). mkdirs (); FileOutputStream fileOutputStream = ny FileOutputStream (fil); Skribentforfatter = Ny BufferedWriter (Ny OutputStreamWriter (FileOutputStream)); prøv writer.write (text); writer.flush (); fileOutputStream.getFD () synk (.); endelig writer.close ();
For å ringe metoden ovenfor må vi omgir den i en prøv ... fange
blokk for å håndtere unntaket.
prøv editFile (ny fil (""), "min tekst"); fangst (IOException e) e.printStackTrace ();
Dette har vært en kort titt på unntak i Java. La oss nå se hvordan Kotlin håndterer unntak.
Hovedforskjellen mellom Kotlin og Java-unntaksmekanismer er at alle unntakene er ukontrollerte i Kotlin. Med andre ord, de er ikke eksplisitt erklært i funksjons signaturene, som de er i Java.
morsom editFile (fil: fil, tekst: streng) file.parentFile.mkdirs () val fileOutputStream = FileOutputStream (fil) val writer = BufferedWriter (OutputStreamWriter (fileOutputStream)) prøv writer.write (text) writer.flush () fileOutputStream .fd.sync () endelig writer.close ()
Her har vi konvertert editFile ()
metode til en Kotlin-funksjon. Du kan se at funksjonen ikke har kaster IOException
uttalelse i sin funksjons signatur. kaster
er ikke engang et søkeord i Kotlin.
Også, vi kan ringe denne funksjonen uten å omgjøre den med prøv ... fange
blokkere og kompilatoren vil ikke klage. Med andre ord er det ikke slikt som sjekkede unntak i Kotlin. Alle unntak er ikke merket. (Merk at hvis det er et unntak kastet, stopper programgjennomgangen som normalt.)
Hvis vi mener at dette unntaket kan oppstå, bør vi fortsatt håndtere det ved å omgjøre metoden med a prøv ... fange
blokk - men dette håndheves ikke av Kotlin-kompilatoren.
prøv editFile (File (""), "text 123") fangst (e: IOException) e.printStackTrace ()
Hvis unntaket kastet inne i editFile ()
funksjon er en forekomst av IOException
klasse, vår å fange
blokkering vil bli utført, og vi skriver ut stablingssporet for feilsøkingsformål.
prøv ... fange
BlokkereDe prøve
konstruere med å fange
og endelig
Klausuler i Kotlin ligner på Java.
morsom foo () prøv kaste Unntak ("Unntaksmelding") fangst (e: Unntak) println ("Unntatt håndtert") til slutt println ("inside finally block")
Her kaster vi en Unntak
objekt inni prøve
blokkere. Legg merke til at vi ikke inkluderte ny
søkeord som vi gjør i Java for å opprette en ny forekomst. Vær også oppmerksom på at vi ikke angav unntaket som vil bli kastet i funksjons signaturen som vi måtte i Java.
Vi håndterer alle underklasser og klasser av typen Unntak
i fangstblokken. Den valgfrie endelig
blokkering utføres alltid - dette er hvor vi vanligvis lukker eventuelle ressurser eller tilkoblinger som tidligere ble åpnet for å forhindre ressurslekkasjer. Hvis du for eksempel åpner en fil eller oppretter en database eller nettverksforbindelse i en prøve
blokkere, bør du lukke eller frigjøre den i en endelig
blokkere.
Legg merke til at i Kotlin den kaste
konstruere er et uttrykk og kan kombinere med andre uttrykk.
val brev = 'c' valresultat = hvis (bokstav i 'a' ... 'z') brev annet kaste IllegalArgumentException ("Et brev må være mellom a til z")
Også, den prøve
konstruksjon kan brukes som et uttrykk.
morsom foo (nummer: Int) valresultat = prøve hvis (tall! = 1) kaste IllegalArgumentException () true fangst (e: IllegalArgumentException) false println (resultat) foo (2) // false
Her tildelte vi verdien returnert fra prøv ... fange
blokkere til resultat
variabel. Hvis nummeret ikke er det 1
, det kaster en IllegalArgumentException
og å fange
blokkering er utført. De falsk
uttrykk i å fange
blokkverdi vil bli tildelt til resultat
variabel. Hvis nummeret er 1
i stedet da ekte
uttrykksverdien vil bli tildelt til resultat
variabel.
Unntak i Kotlin oppfører seg som vanlig i Java, men jeg vil gjøre deg oppmerksom på en nyttig merknad som heter @Throws
i Kotlin som kan komme til nytte. Fordi alle unntak i Kotlin ikke er merket, kan utviklere som bruker Kotlin-koden fra Java, ikke være oppmerksom på at funksjonene dine kaster unntak. Du kan imidlertid fortsatt legge til mulige unntak som kan bli kastet til en metode underskrift med @Kaste
merknad. Dette vil varsle Java-oppringere som de trenger for å håndtere unntaket.
La oss se et praktisk eksempel på denne merknaden.
/ * Functions.kt fil * / morsomt addNumberToTwo (a: Enhver): Int hvis (a! Er Int) kaste IllegalArgumentException ("Nummer må være et heltall") returnere 2 + a
Her definerte vi en Kotlin-funksjon som kan kaste et unntak IllegalArgumentException
bare hvis typen som er overført til funksjonen ikke er av typen int
.
Vi kaller denne toppnivåfunksjonen addNumberToTwo ()
direkte fra Java på følgende måte:
offentlig tomrom myJavaMethod () Integer resultat = FunksjonerKt.addNumberToTwo (5); System.out.println (resultat); // 7
Dette fungerer fint; kompilatoren klager ikke. Men hvis vi ønsker å kommunisere med Java-oppringere at addNumberToTwo ()
toppnivå funksjon kaster et unntak, vi legger ganske enkelt til @Throws
annotasjon til funksjons signaturen.
@Throws (IllegalArgumentException :: class) morsomt addNumberToTwo (en: Enhver): Int hvis (a! Er Int) kaste IllegalArgumentException ("Nummer må være et heltall") returnere 2 + a
Dette @Throws
annotering kan akseptere en kommaseparert liste over argumenter for unntaksklasser. I koden ovenfor inkluderte vi bare ett unntaksklasse-IllegalArgumentException
.
Nå må vi oppdatere vår Java-kode for å håndtere unntaket.
offentlig tomrom myJavaMethod () kaster ulovligArgumentException Integer resultat = FunksjonerKt.addNumberToTwo (5); System.out.println (resultat);
Hvis vi dekompilere Kotlin addNumberToTwo ()
funksjon, bruk av Vis Kotlin Bytecode funksjonen (hvis du er i IntelliJ IDEA eller Android Studio, bruk Verktøy > Kotlin > Vis Kotlin Bytecode), ser vi følgende Java-kode:
// ... offentlig statisk endelig int addNumberToTwo (@NotNull Object a) kaster ulovligArgumentException Intrinsics.checkParameterIsNotNull (a, "a"); hvis (! (en forekomst av Integer)) kaste (Kastbar) (ny ulovligArgumentException ("tall må være et heltall")); ellers return 2 + ((Nummer) a) .intValue (); // ...
I den genererte Java-koden ovenfor (noen elementer i den genererte koden ble fjernet for korthetens skyld), kan du se at kompilatoren la til kaster
søkeord til metoden signatur - fordi vi inkluderte @Throws
merknad.
I denne opplæringen lærte du mer om programmering i Kotlin ved å se på unntak. Vi så at Kotlin ikke har sjekket unntak, men at alle unntakene i stedet er ukontrollerte. Vi så også på hvordan du skal håndtere unntak ved å bruke prøv ... fange
blokkere og se nytten av @Throws
annotasjon i Kotlin for Java-oppringere.
For å lære mer om Kotlin-språket, anbefaler jeg at du besøker Kotlin-dokumentasjonen. Eller sjekk ut noen av våre andre Android-apputviklingsposter her på Envato Tuts!