Kotlin actual combat [v] anomalies in kotlin

Keywords: Java kotlin

1, How kotlin throws exceptions

Exception handling in Kotlin is similar to that in Java or other languages. A function can end normally or throw an exception when an error occurs. The function caller catches the exception and handles it; If not, the exception is thrown up the call stack again.

The basic form of exception handling statements in Kotlin is similar to that in java:

if(0 <= percentage <= 100){
  throw new IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage") ;
}

In kotlin: (different from java, you don't have to use new to create an instance)

if (percentage !in 0..100) {
    throw IllegalArgumentException( "A percentage value must be between 0 and 100: $percentage")
}

Not only that, the throw structure in kotlin is an expression that can be used as part of another expression:

val percentage =
    if (number in 0..100)
        number
    else
        throw IllegalArgumentException( //"throw" is an expression
            "A percentage value must be between 0 and 100: $number")

In this example, if the conditions are met and the behavior of the program is correct, the percentage will be initialized with number, otherwise the exception will be thrown and the variable will not be initialized.

2, "try", "catch", "finally"

Just like in Java, you can use the try structure, catch and finally clauses to handle exceptions.

As follows, read a line of the specified file, try to parse it into a number, and then return a number. If this line is not a valid number, return null.

fun readNumber(reader: BufferedReader): Int? { //You don't have to explicitly specify the exceptions that this function might throw
    try {
        val line = reader.readLine()
        return Integer.parseInt(line)
    } catch (e: NumberFormatException) { //The type of exception is on the right
        return null
    } finally { //finally, it's like in Java
        reader.close()
    }
}
val reader = BufferedReader(StringReader("239"))
println(readNumber(reader))
//239

In java:

public int readNumber(BufferedReader reader) throws IOException{ //Explicitly specify the exceptions that this function may throw
  try {
      String line = reader.readLine()
      return Integer.parseInt(line)
  } catch (NumberFormatException e) {
      return null
  } finally {
      reader.close()
  }
}

From the comparison, we can see that the biggest difference between kotlin and Java is that the throws clause is not required. In Java, this kind of exception must be handled as shown, and all checked exceptions that may be thrown by your function must be declared. If you call another function, you need to handle the checked exceptions of this function, or declare these exceptions that your function may throw.

Unlike other modern JVM languages, Koltin does not distinguish between checked and unchecked exceptions. You need to specify the exceptions thrown by a function, and you can or can not handle these exceptions. This design decision is based on the practice of using checked exceptions in Java. Experience has shown that Java rules often require a lot of meaningless code to throw or ignore exceptions again, and these rules can not always protect you from your mistakes.

In the above example, NumberFormatException is an unchecked exception. So the Java compiler won't force you to catch this exception. You can easily see the exception at run time. This is quite regrettable, because ineffective input data is a common thing and should be handled more gracefully. At the same time, the BufferedReader.close method can also throw an IOException, which is a checked exception to be handled. If closing a flow fails, most of the code cannot take any meaningful action, so the code that needs to catch exceptions from the close method is basically template code.

3, try as an expression

To show an important difference between Java and Kotlin, let's change this example a little. Remove the fianlly part (because you already know how this works), and then add some code to print the numbers read from this file.

fun readNumber(reader: BufferedReader) {
    val number = try {
        Integer.parseInt(reader.readLine()) //Becomes the value of the try expression
    } catch (e: NumberFormatException) {
        return
    }
    println(number)
}

val reader = BufferedReader(StringReader("not a number"))
readNumber(reader)//No numbers were printed

The try keyword in Kotlin, like if and when, introduces an expression that you can assign its value to a variable. Unlike if, you always need to put statements in curly braces. Like other statements, if multiple expressions are included, the value of the try expression is the value of the last expression. In this example, there is a return statement in the catch code block, so this function will not be performed after the catch code block. If you want to continue the execution, the catch statement also needs a value, which is the value of the last expression:

fun readNumber(reader: BufferedReader) {
    val number = try {
        Integer.parseInt(reader.readLine()) //Use this value when no exception occurs
    } catch (e: NumberFormatException) {
        null //Use null value when exception occurs
    }
    println(number)
}
val reader = BufferedReader(StringReader("not a number"))
readNumber(reader)//The exception is thrown, so the function prints null
//null

If a try code block performs normally, the last expression in the code block is the result. If an exception is caught, the last expression in the cache code block is the result.

4, Summary

  • 1. The exception handling in kotlin is similar to that in java, except that kotlin does not require you to declare exceptions that functions can throw.
  • 2. If a try code block performs normally, the last expression in the code block is the result.
  • 3. If an exception is caught, the last expression in the cache code block is the result.

This article is transferred from https://cloud.tencent.com/developer/article/1397852 , in case of infringement, please contact to delete.

Related videos:

Android advanced learning: Kotlin core technology_ Beep beep beep_ bilibili
Android network architecture construction and principle analysis (I) -- witness the growth of network modules step by step through a network request_ Beep beep beep_ bilibili
[advanced Android course] - explanation of colin Compose's drawing principle (I)_ Beep beep beep_ bilibili
[advanced Android tutorial] - Handler source code analysis for Framework interview_ Beep beep beep_ bilibili
[advanced Android tutorial] - Analysis of hot repair Principle_ Beep beep beep_ bilibili
[advanced Android tutorial] - how to solve OOM problems and analysis of LeakCanary principle_ Beep beep beep_ bilibili

Posted by Jtech on Tue, 09 Nov 2021 14:04:02 -0800