class MyException() : Exception() //自定义异常
- fun check(num: Int?) {
- num ?: throw MyException() //抛异常
- checkNotNull(num) {"值为空"} //使用先决条件函数
- }
- try {
- //业务代码...
- } catch(e: Exception) {
- //异常处理...
- } finally {
- //关闭资源...
- }
强烈建议使用 Kotlin 函数式风格或者链式风格编程。runCatching( ) 会返回一个 Result 对象,通过调用它的 onSuccess() 来处理成功,onFailure() 来处理失败。若要关闭资源,老老实实写 try-catch。
| public inline fun return try { Result.success(block()) } catch (e: Throwable) { Result.failure(e) } } |
- runCatching {
- //业务代码
- }.onSuccess {
- //成功时...
- }.onFailure { throwable ->
- //失败时,异常处理...
- }
配置一个默认的方案来处理那些未捕获的异常。在APP崩溃时能记录错误(尤其是不好复现的bug)或崩溃前呈现用户友好消息。
- private fun defaultUnCaughtExceptionHandler(){
- Thread.setDefaultUncaughtExceptionHandler { thread, exception ->
- Log.e("未捕获异常","${exception.message}")
- Toast.makeText(this, "Oops!",Toast.LENGTH_LONG).show()
- exception.printStackTrace()
- }
- }
条件必须满足,代码才会继续往下执行。
| require( ) | check( ) | assert( ) | |
| 相同 | 如果参数值为 false 抛出异常,为 true 代码继续往下执行。 | ||
| 区别 | 对外:检查传入的参数。 | 对内:检查自身状态。 | 检查是否和预估相符 |
| require( ) + check( ) = 检查前置条件,通过了才可以执行真正的业务逻辑。 | 后置条件:确保结果符合预期 | ||
| 抛出 IllegalArgumentException | 抛出 IllegalStateException | 抛出 AssertionError | |
| requireNotNull( ) | checkNotNull( ) | error( ) | |
| 相同 | 如果参数值为 null 抛出异常,否则返回 非null 值。 | ||
| 区别 | 对外:检查传入的参数。 | 对内:检查自身状态。 | ? |
| requireNotNull( ) + checkNotNull( ) = 检查前置条件,通过了才可以执行真正的业务逻辑。 | ? | ||
| 抛出 IllegalArgumentException | 抛出 IllegalStateException | 抛出 IllegalStateException | |
| public value class Result |
对于一些需要关心结果的操作,成功时需要得到数据,失败时需要得到信息。返回的 Result 只能是 success 或 failure 中的一种,success持有一个泛型数据T,failure持有一个异常Throwable。
是一个 value class 意味着是为了安全用来对数据进行包装(装箱)的强类型,返回值是 Serializable 意味着被包装的数据类型需要实现序列化否则抛异常 NotSerializableException。泛型是
上限定意味着只能作为生产者,即结果只能被读取。形参类型是 Any? 因为成功传入的是值T失败传入的是异常Throwable。
| success( ) failure( ) | public inline fun //成功时调用,来包装返回的值。 public inline fun //失败时调用,来包装返回的异常。 |
| .isSuccess .isFailure | public val isSuccess: Boolean get() = value !is Failure 返回的结果是成功吗 public val isFailure: Boolean get() = value is Failure 返回的结果是失败吗 |
| onSuccess( ) onFailure( ) | public inline fun public inline fun 返回的结果是成功或失败时的回调,做一些操作。 |
| getOrNull( ) getOrThrow( ) getOrElse( ) getOrDefault( ) | public inline fun getOrNull(): T? 返回的结果是成功就得到值,失败就得到null,不关心异常。 public inline fun 返回的结果是成功就得到值,失败就抛异常,不处理异常。 public inline fun 返回的结果是成功就得到值,失败就执行传入的onFailure来处理异常并返回一个值。 public inline fun 返回的结果是成功就得到值,失败就得到默认值。 |
| exceptionOrNull( ) | public fun exceptionOrNull(): Throwable? 返回的结果是失败就得到异常,成功就得到null,不关心值。 |
| runCatching( ) | public inline fun public inline fun 执行block,成功就返回值,发生异常就返回失败。 |
| fold( ) | public inline fun 返回的结果是成功就执行传入的onSuccess将T值转换成R值返回, 返回的结果是失败就执行传入的onFailure来处理异常并返回一个值。 |
| map( ) mapCatching( ) | public inline fun 返回的结果是成功就执行传入的transform将T值转换成R值返回, 返回的结果是失败或者执行传入的transform发生异常都返回异常。 public inline fun 返回的结果是成功就组合执行runCatching(transform),transform将T值转换成R值,执行成功就返回R值,执行异常就返回异常。 返回的结果是失败或者执行传入的transform发生异常都返回异常。 |
| recover( ) recoverCatching( ) | public inline fun 返回的结果是成功就返回值, 返回的结果是失败就执行传入的transform处理异常并返回一个值。 public inline fun 返回的结果是成功就返回值, 返回的结果是失败就执行传入的transform处理异常并返回一个值,执行成功就返回值,执行失败就返回异常。 |
- val boolean = true
- fun demo() = if (boolean) Result.success(123) else Result.failure(Exception())
- val result = demo()
- println(result.isFailure) //打印:false
- result.onSuccess { println(it) } //打印:123
- val recover = result.recover { 5 }
- println(recover) //打印:Success(123)