面试题:协程异常处理器及try catch

在 Kotlin 协程里,异常处理器(CoroutineExceptionHandler)和 try-catch 块在处理异常时各有特点,它们之间存在一定的包含关系,下面详细介绍:

1. try-catch 块

在协程内部使用 try-catch 块可以捕获并处理局部异常。它的作用范围仅限于所在的协程体,仅能捕获该协程体中抛出的异常。

import kotlinx.coroutines.*

fun main() = runBlocking {
    val job = launch {
        try {
            throw RuntimeException("Exception in coroutine")
        } catch (e: RuntimeException) {
            println("Caught exception in try-catch: ${e.message}")
        }
    }
    job.join()
}

在这个例子中,try-catch 块捕获了协程体中抛出的 RuntimeException,并进行了处理。

2. 异常处理器(CoroutineExceptionHandler

CoroutineExceptionHandler 是一个用于全局处理未捕获异常的处理器。它可以在协程作用域或者协程构建器中设置,当协程中抛出未被 try-catch 捕获的异常时,会触发异常处理器。

import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
    }
    val job = GlobalScope.launch(handler) {
        throw RuntimeException("Exception in coroutine")
    }
    job.join()
}

在这个例子中,由于协程体中没有使用 try-catch 块捕获异常,所以异常被 CoroutineExceptionHandler 捕获并处理。

3. 包含关系

  • try-catch 优先处理:当协程中抛出异常时,try-catch 块会首先尝试捕获并处理异常。如果异常被 try-catch 块捕获,那么异常处理器(CoroutineExceptionHandler)将不会被触发。
import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
    }
    val job = launch(handler) {
        try {
            throw RuntimeException("Exception in coroutine")
        } catch (e: RuntimeException) {
            println("Caught exception in try-catch: ${e.message}")
        }
    }
    job.join()
}

在这个例子中,try-catch 块捕获了异常,所以 CoroutineExceptionHandler 不会被触发。

  • 异常处理器处理未捕获异常:如果 try-catch 块没有捕获到异常,那么异常会被传递给异常处理器(CoroutineExceptionHandler)进行处理。
import kotlinx.coroutines.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("Caught exception in CoroutineExceptionHandler: ${exception.message}")
    }
    val job = launch(handler) {
        throw RuntimeException("Exception in coroutine")
    }
    job.join()
}

在这个例子中,由于协程体中没有使用 try-catch 块捕获异常,所以异常被 CoroutineExceptionHandler 捕获并处理。

综上所述,try-catch 块用于处理协程内部的局部异常,而异常处理器(CoroutineExceptionHandler)用于处理未被 try-catch 块捕获的全局异常。它们之间是一种互补的关系,共同保证了协程中异常的有效处理。

你可能感兴趣的:(面试,kotlin,android)