Kotlin Try Catch

Using the Try/Catch statement in Kotlin.

fun main() {
    println(getNumber("22")) // returns 22
    println(getNumber("22.5")) // returns 0
    println(getNumber2("33") ?: "I can't print the result") // Use null return to determine output
    println(getNumber2("33.5") ?: IllegalArgumentException("Number isn't an Int")) // Use null return to throw a different Exception

    notImplementedYet("Yep")
}
// Don't have to declare the exceptions that Kotlin throws as it does not distinguish between checked and unchecked exceptions. Try/catch can be used as an expression.
fun getNumber(string: String): Int {
    return try {
        Integer.parseInt(string)
    }
    catch (e: NumberFormatException) {
        0
    }
    finally {
        println("I'm in the finally block") // Will print regardless of outcome. Prints before the result as it gets executed and then the function returns the result.
        1 // Does not feature as the finally block is not involved in the execution of the function
    }
}
//If you want to return null instead of throwing an exception:
fun getNumber2(string: String): Int? {
    return try {
        Integer.parseInt(string)
    }
    catch (e: NumberFormatException) {
        null
    }
    finally {
        println("I'm in the finally block")
    }
}
// A developer might implement a function that will always throw an Exception since it has not been completed yet - as a reminder to themselves and other developers that code is incomplete:
fun notImplementedYet (something: String): Nothing { // Makes it clear to developers that this code will never return a value
    throw IllegalArgumentException("Implement me!")
}

 

Datatypes

Datatype rules for Kotlin.

fun main() {
    val myInt = 10
    println("default datatype is ${myInt is Int}")
    var myLong = 22L
    // Every datatype has .toXxxx() functions to convert to another type. In Kotlin, you cannot declare myLong = myInt and expect it to expand the data type.
    myLong = myInt.toLong()

    val myByte: Byte = 111
    var myShort: Short
    myShort = myByte.toShort()

    var myDouble = 65.984 // Defaults to a Double
    println(myDouble is Double) // As proof

    val myFloat = 838.9823f // f declares it a Float
    println(myFloat is Float) // As proof

//    myDouble = myFloat // Will fail - no expansion
    myDouble = myFloat.toDouble()

    val char = 'b' // Defaults to Char
//    char myChar = 65 // In Java would call the char of value 65 = 'A'
    val myChar = 65 // In Kotlin, obviously produces a very different result!
//    val myChar2: Char = 65 // Fails, does not conform to data type
    val myCharInt = 65
    println(myCharInt.toChar()) // => A

    // When calling Java from Kotlin, how do we provide primitive types since they don't exist in Kotlin?
    val vacationTime = false
    val onVacation = DummyClass().isVacationTime(vacationTime)
    println(onVacation) // Works because the Kotlin datatype classes compile down to primitives. Also works if Java is expecting Boolean due to Java boxing.

    // Any, Unit, Nothing classes
    // Any is Kotlin root class
    val anything: Any
    // Unit class is equivalent to void. A Singleton instance of Unit is returned instead of nothing
    // Nothing class is subclass of Any class. Could use when e.g. you know something will never return
}