Tagalog (Wikang Tagalog) translation by Robert Alexander (you can also view the original English article)
Ang Kotlin ay isang modernong programming language na nagko-compile sa
Java bytecode. Ito ay libre at open source, at pinapasaya nito ang pagko-code
sa Android.
Sa nakaraang artikulo, mas higit ninyong natutunang ang tungkol sa object-oriented programming sa pamamagitan ng pagsiyasat pa sa mga abstract classes, interfaces, inheritance, at type aliases sa Kotlin.
Sa post na ito, patuloy ninyong matututunan ang tungkol sa pagpo-program sa Kotlin sa pamamagitan ng pag-aaral tungkol sa exceptions at kung papaano ito iha-handle.
1. Exception Handling
Ang mga exceptions ay ginagamit upang matukoy ang isang problema sa ating code habang ine-execute ito. Ang exception handling ay ang kakayahan na tukuyin (o i-handle) ang exception na maaaring maganap. Kung hindi natin iha-handle ang exception na mangyayari, ang program natin ay titigil sa pag-gana at biglaang isasara ang app natin kaagad.
Binibgiyan ng exception handling ang ating program ng kakayahan na ituloy ang pagtakbo kahit na mayroong exception (gayunpaman, higit na inirerekumenda na i-log ang iyong mga exceptions at iulat ang mga ito gamit ang isang crash reporting tool gaya ng Crashlytics).
Sa Java, mayroon tayong dalawang klase ng exceptions: ang checked at ang unchecked. Ipapaliwanag ko ng mabilis ang dalawa, ngunit magsisimula tayo sa unchecked exceptions.
Ang Unchecked Exceptions
Ito ay ang mga
exceptions na binigay dahil sa mga pagkakamali sa ating code. Ang mga ito ay
isang direkta o di direktang subclass ng RunTimeException
superclass.
Ang mga halimbawa ng unchecked excemptions ay kinapapalooban ng:
-
ArithmeticException
: binibigay kapag nagdivide ka sa zero. -
ArrayIndexOutOfBoundExceptions
: binibigay kapag ang isang array ay inaccess gamit ang isang ilegal na index. -
SecurityException
: binibigay ng security manager upang tumukoy ng isang security violation. -
NullPointerException
: binibigay kapag tumatawag ng isang method o property sa isang null object.
Ang isang method
na maaaring magbigay ng unchecked exception ay hindin naglalaman ng kahit na
anong kaalaman tungkol sa exception na ibinigay sa method declaration nito.
public Integer divideByZero(Integer numerator, Integer denominator) { return numerator / denominator; } divideByZero(7, 0) // throws ArithmeticException
Maiiwasan ang mga
tipo ng exception na ito sa pamamagitan ng pag-code ng tama. Sa code sa itaas,
dapat ay na-check natin kung ang denominator ay zero bago gawin ang operation. Para sa mga
exceptions na ito, hindi kailangang mahuli ng developer ang exception gamit ang try…catch
na block. Sa madaling sa
lita, hindi tayo pinipilit ng compiler na sakupin ang code na maaaring
mag-trigger ng exception sa isang try…catch
block. Sa halip, kailangan lang
nating siguruhing hindi talaga mangyayari ang mga exceptions na ito.
Isa pa, tandaan
natin na ang Kotlin ay isang null safe na language. Sa madaling salita, maaari
tayong tulungan nitong hindi magkaroon ng NullPointerExceptions
sa ating code.
Maaari ninyong basahin ang Nullability, Loops at mga Conditions na post para
muling sariwain ang tungkol sa null safety sa Kotlin.
Mga Checked Exceptions sa Java
Ang isang method
na maaaring magbigay ng isang checked exception ay kailangang ideklara ito sa
method signature nito gamit ang throws
na keyword. Kung tatawag ka ng isang
method na magbibigay ng isang checked exception, maaaring kailangan mo itong
ibigay muli mula sa iyong function o hulihin at i-handle ito gamit ang isang try…catch
block.
Ang mga checked
exceptions ay mga exceptions na nakuha sa oras ng pagcompule. Ang ganitong
klase ng exceptions ay nag-iinherit mula sa Exception
class. Ang isang
halimbawa ng ganitong exception ay ang IOException
. Maaari itong
mangyari kapag sinubukan ninyong mag-access ng isang file na hindi mabubuksan
dahil hindi ito umiiral. (Ang FileNotFoundException
ay isang subclass ng
IOException
.)
// perform in a background thread public void editFile(File file, String text) { try { file.getParentFile().mkdirs(); FileOutputStream fileOutputStream = new FileOutputStream(file); Writer writer = new BufferedWriter(new OutputStreamWriter(fileOutputStream)); try { writer.write(text); writer.flush(); fileOutputStream.getFD().sync(); } finally { writer.close(); } } catch (IOException e) { // Log the exception e.printStackTrace(); } }
Sa naunang code,
gumamit tayo ng try…catch
block para asikasuhin ang IOException
sa loob ng
editFile(
) na method. Maaari na nating tawagin ang editFile()
method ng normal,
at ang compiler ay hindi magrereklamo.
editFile(new File(""), "my text");
Sa pagtingin sa
code sa ibaba, kinalikot natin ang method para sa halip ay gamitin nito ang
throws
keyword sa method signature. Ipinapakita nito sa mga tagatawag na
kailangan nilang i-handle ang exception na IOException
na maaaring ibigay kapag
tinatawag ang method na editFile()
.
// this should be in a background thread public void editFile(File file, String text) throws IOException { file.getParentFile().mkdirs(); FileOutputStream fileOutputStream = new FileOutputStream(file); Writer writer = new BufferedWriter(new OutputStreamWriter(fileOutputStream)); try { writer.write(text); writer.flush(); fileOutputStream.getFD().sync(); } finally { writer.close(); } }
Para tawagin ang
method sa itaas, kailangan natin itong palibutan sa isang try…catch
block upang
ma-handle ang exception.
try { editFile(new File(""), "my text"); } catch (IOException e) { e.printStackTrace(); }
Ang lahat ng ito ay maiikling pasilip lamang sa mga exceptions sa Java. Ngayon naman ay tignan natin kung papaano hinahandle ng Kotlin ang mga exceptions.
2. Ang mga Exceptions sa Kotlin
Ang
pinakapinagkaiba ng mga exception mechanisms ng Kotlin at Java ay ang lahat ng
exceptions ay unchecked sa Kotlin. Sa madaling salita, ang mga ito ay hindi
tuwirang nakadeklara sa mga function signature, hindi gaya ng sa Java.
fun editFile(file: File, text: String) { file.parentFile.mkdirs() val fileOutputStream = FileOutputStream(file) val writer = BufferedWriter(OutputStreamWriter(fileOutputStream)) try { writer.write(text) writer.flush() fileOutputStream.fd.sync() } finally { writer.close() } }
Dito ay
na-convert natin ang editFile()
method sa isang Kotlin function. Makikita
ninyong ang function ay walang throws IOException
na statement sa function
signature nito. Ni hindi keyword ang throws
sa Kotlin.
Isa pa, maaari
nating tawagin ang function na ito ng hindi ito pinapaligiran ng try…catc
h
block-at hindi magrereklamo ang compiler. Sa madaling
salita, walang checked exceptions sa Kotlin. Lahat ng exceptions ay unchecked,
(Tandaan na kung mayroong isang exception na ibinato, ang program execution ay
titigil ng normal.)
Kung tingin natin
na ang exception na ito ay sisibol, dapat pa rin natin itong i-handle sa
pamamagitan ng pagligid sa function sa isang try…catch
block-ngunit hindi ito
pinapatupad ng compiler ng Kotlin.
try { editFile(File(""), "text 123") } catch (e: IOException) { e.printStackTrace() }
Kung ang
exception ay ibinato sa loob ng editFile()
function ay isang instance ng
IOException
class, ang ating catch
block ay mapapatupad, at ipi-prit lang natin
ang stack trace para sa proseso ng debugging.
Ang try...catch
Block
Ang try
na
construct na mayroong catch
at finally
na mga sugnay sa Kotlin ay pareho sa
Java.
fun foo() { try { throw Exception("Exception message") } catch (e: Exception) { println("Exception handled") } finally { println("inside finally block") } }
Dito, nagbabato
tayo ng isang Exception
object sa loob ng tr
y block. Pansinin na hindi natin
sinama ang bagong
keyword gaya ng ginagawa natin sa Java para makagawa ng isang
bagong instance. Pansinin din
natin na hindi natin tiniyak ang exception na ibabao sa function signature gaya
ng ginagawa natin sa Java.
Ihina-handle
natin ang lahat ng subclasses at classes na may type Exception
sa catch block.
Ang pagpipiliang finally
block ay laging gumagana — dito natin isniasara ang
kahit na anong resources o connections na binuksan dati para maiwasan ang
paglabas ng mga resource. Halimbawa, kung
nagbukas kayo ng isang file o gumawa ng isang database o network connection sa
isang try
block, dapat ay maisasara mo o mapapakawalan mo ito sa isang finally
block.
Tandaan na sa
Kotlin, ang throw
na construct ay isang expression at maaaring isama sa iba
pang expressions.
val letter = 'c' val result = if (letter in 'a'..'z') letter else throw IllegalArgumentException("A letter must be between a to z")
Isa pa, maaari
ding gamitin ang try
construct bilang isang expression.
fun foo(number: Int) { val result = try { if (number != 1) { throw IllegalArgumentException() } true } catch (e: IllegalArgumentException) { false } println(result) } foo(2) // false
Dito ay itinakda
natin ang value na ibabalik mula sa try…catch
block sa result
variable. Kung
ang numero ay hindi 1
, magbabato ito ng isang IllegalArgumentExceptiom
at
mapapagana ang catch
block. Ang false
expression sa catch
block value ay itatakda sa result
variable. Kung ang
numero, sa halip, ay 1
, ang true
expression value ay itatakda sa result
variable.
Java Interop
Ang mga exceptions
sa Kotlin ay kikilos ng normal sa Java — ngunit gusto kong malaman ninyo ang
isang kapaki-pakinabang na annotation na tinatawag na @Throws
sa Kotlin na
maaaring magamit. Dahil lahat ng
exceptions sa Kotlin ay unchecked, ang mga developers na gumagamit ng iyong
Kotlin code mula sa Java ay maaaring hindi alam na ang iyong functions ay
nagbabato ng exceptions. Gayunpaman,
maaari ka pa ring magdagdag ng mga possibleng exceptions na maaaring ibato sa
isang method signature gamit ang @Throw
na annotation. Aalertuhin nito ang mga
tagatawag sa Java na kailangan nilang i-handle ang exception.
Tignan natin ang isang praktikal na halimbawa ng annotation na ito.
/* Functions.kt file */ fun addNumberToTwo(a: Any): Int { if (a !is Int) { throw IllegalArgumentException("Number must be an integer") } return 2 + a }
Dito, tinukoy
natin ang isang Kotlin function na maaaring magbato ng isang exception na
IllegalArgumentException
tanging kapag ang tipong ipinasa sa function ay hindi
type Int
.
Tinatawag natin
ang top-level function na addNumberToTwo()
ng direkta mula sa Java sa sumusunod
na paraan:
public void myJavaMethod() { Integer result = FunctionsKt.addNumberToTwo(5); System.out.println(result); // 7 }
Gumagana ito ng
maayos; hindi nagrereklamo ang compiler. Gayunpaman, kung gusto nating ipaaalam
sa mga tagatawag ng Java na ang addNumberToTwo()
na top-level function ay
magbabato ng isang exception, idadagdag lang natin ang @Throws
annotation sa
function signature.
@Throws(IllegalArgumentException::class) fun addNumberToTwo(a: Any): Int { if(a !is Int) { throw IllegalArgumentException("Number must be an integer") } return 2 + a }
Ang @Throws
annotation na ito ay maaaring tumanggap ng isang comma-separated na listahan ng
mga arguments ng exception classes. Sa code sa ideaas, nagsama lang tayo ng
isang exception class — ang IllegalArgumentException
.
Ngayon ay kailangan nating i-update ang ating Java code para maghandle ng exception.
public void myJavaMethod() throws IllegalArgumentException { Integer result = FunctionsKt.addNumberToTwo(5); System.out.println(result); }
Kung
ide-decompile natin ang addNumberToTwo()
function ng Kotlin, gamit ang Show Kotlin Bytecode na
feature (kung nasa IntelliJ Idea o Android Studio ka, gamitin ang Tools > Kotlin > Show Kotlin Bytecode), makikita
natin ang sumusunod na Java code:
// ... public static final int addNumberToTwo(@NotNull Object a) throws IllegalArgumentException { Intrinsics.checkParameterIsNotNull(a, "a"); if (!(a instanceof Integer)) { throw (Throwable)(new IllegalArgumentException("Number must be an integer")); } else { return 2 + ((Number)a).intValue(); } } // ...
Sa generated na
Java code sa itaas (ang ilang element ng generated code ay tinanggal para
Makita ang pagkakaiba), makikita ninyo na dinagdag ng compiler ang throws
keyword sa method signature-dahil isinama natin ang @Throws
na annotation.
Konklusyon
Sa pagtuturong
ito, higit ninyong natutunan ang tungkol sa pagpoprogram sa Kotlin sa
pamamagitan ng pagtingin sa mga exceptions. Nakita natin na ang Kotlin ay
walang mga checked exceptions ngunit sa halip ay lahat ng exceptions dito ay
unchecked. Tinginan din
nating kung papaano maghandle ng exceptions gamit ang try…catch
block at nakita
ang kapakinabangan ng @Throws
na annotation sa Kotlin para sa mga tagatawag ng
Java.
Para mas matutunan pa ang tungkol sa Kotlin language, nirerekumenda kong puntahan ang documentation ng Kotlin. O tignan ang iba pa naming posts tungkol sa pagdevelop ng Android app dito sa Envato Tuts!
- Android SDKJava vs. Korlin: Dapat Bang Gumagamit Ka ng Kotlin Para sa Android Development?Jessica Thornsby
- Android SDKPagpapakilala sa Mga Architecture Components ng AndroidTin Megali
- Android SDKMagsimula Gamit ang RxJava 2 para sa AndroidJessica Thornsby
- Android SDKAng Concurrency sa RxJava2Chike Mgbemena