Kotlin - 异常、先决条件函数、Result

一、异常处理

1.1 自定义异常

class MyException() : Exception()    //自定义异常

1.2 抛出异常

fun check(num: Int?) {
    num ?: throw MyException()    //抛异常
    checkNotNull(num) {"值为空"}    //使用先决条件函数
}

1.3 捕获异常

1.3.1 try-catch-finally

try {
    //业务代码...
} catch(e: Exception) {
    //异常处理...
} finally {
    //关闭资源...
}

1.3.2 runCatching( )

强烈建议使用 Kotlin 函数式风格或者链式风格编程。runCatching( ) 会返回一个 Result 对象,通过调用它的 onSuccess() 来处理成功,onFailure() 来处理失败。若要关闭资源,老老实实写 try-catch。

public inline fun <R> runCatching(block: () -> R): Result<R> {
    return try {
        Result.success(block())
    } catch (e: Throwable) {
        Result.failure(e)
    }
}
runCatching { 
    //业务代码
}.onSuccess { 
    //成功时...
}.onFailure { throwable -> 
    //失败时,异常处理...
}

1.4 全局默认异常处理

配置一个默认的方案来处理那些未捕获的异常。在APP崩溃时能记录错误(尤其是不好复现的bug)或崩溃前呈现用户友好消息。

private fun defaultUnCaughtExceptionHandler(){
    Thread.setDefaultUncaughtExceptionHandler { thread, exception ->
        Log.e("未捕获异常","${exception.message}")
        Toast.makeText(this, "Oops!",Toast.LENGTH_LONG).show()
        exception.printStackTrace()
    }
}

二、先决条件 Preconditions

条件必须满足,代码才会继续往下执行。

  • 一个参数的版本默认了异常信息,两个参数的版本可以自定义异常信息。
require( )check( )assert( )
相同如果参数值为 false 抛出异常,为 true 代码继续往下执行。
区别对外:检查传入的参数。对内:检查自身状态。检查是否和预估相符
require( ) + check( ) = 检查前置条件,通过了才可以执行真正的业务逻辑。后置条件:确保结果符合预期
抛出 IllegalArgumentException抛出 IllegalStateException抛出 AssertionError
requireNotNull( )checkNotNull( )error( )
相同如果参数值为 null 抛出异常,否则返回 非null 值。
区别对外:检查传入的参数。对内:检查自身状态。
requireNotNull( ) + checkNotNull( ) = 检查前置条件,通过了才可以执行真正的业务逻辑。
抛出 IllegalArgumentException抛出 IllegalStateException抛出 IllegalStateException

三、函数式错误处理 Result

public value class Result<out T>  internal constructor( internal val value: Any? ) : Serializable

        对于一些需要关心结果的操作,成功时需要得到数据,失败时需要得到信息。返回的 Result 只能是 success 或 failure 中的一种,success持有一个泛型数据T,failure持有一个异常Throwable。

        是一个 value class 意味着是为了安全用来对数据进行包装(装箱)的强类型,返回值是 Serializable 意味着被包装的数据类型需要实现序列化否则抛异常 NotSerializableException。泛型是 <out T> 上限定意味着只能作为生产者,即结果只能被读取。形参类型是 Any? 因为成功传入的是值T失败传入的是异常Throwable。

success( )

failure( )

public inline fun <T> success(value: T): Result<T> = Result(value)

//成功时调用,来包装返回的值。

public inline fun <T> failure(exception: Throwable): Result<T> = Result(createFailure(exception))

//失败时调用,来包装返回的异常。

.isSuccess

.isFailure

public val isSuccess: Boolean get() = value !is Failure

返回的结果是成功吗

public val isFailure: Boolean get() = value is Failure

返回的结果是失败吗

onSuccess( )

onFailure( )

public inline fun <T> Result<T>.onSuccess(action: (value: T) -> Unit): Result<T>

public inline fun <T> Result<T>.onFailure(action: (exception: Throwable) -> Unit): Result<T>

返回的结果是成功或失败时的回调,做一些操作。

getOrNull( )

getOrThrow( )

getOrElse( )

getOrDefault( )

public inline fun getOrNull(): T?

返回的结果是成功就得到值,失败就得到null,不关心异常。

public inline fun <T> Result<T>.getOrThrow(): T

返回的结果是成功就得到值,失败就抛异常,不处理异常。

public inline fun <R, T : R> Result<T>.getOrElse(onFailure: (exception: Throwable) -> R): R

返回的结果是成功就得到值,失败就执行传入的onFailure来处理异常并返回一个值。

public inline fun <R, T : R> Result<T>.getOrDefault(defaultValue: R): R

返回的结果是成功就得到值,失败就得到默认值。

exceptionOrNull( )

public fun exceptionOrNull(): Throwable?

返回的结果是失败就得到异常,成功就得到null,不关心值。

runCatching( )

public inline fun <R> runCatching(block: () -> R): Result<R>

public inline fun <T, R> T.runCatching(block: T.() -> R): Result<R>

执行block,成功就返回值,发生异常就返回失败。

fold( )

public inline fun <R, T> Result<T>.fold(
    onSuccess: (value: T) -> R,
    onFailure: (exception: Throwable) -> R
): R

返回的结果是成功就执行传入的onSuccess将T值转换成R值返回,

返回的结果是失败就执行传入的onFailure来处理异常并返回一个值。

map( )

mapCatching( )

public inline fun <R, T> Result<T>.map(transform: (value: T) -> R): Result<R>

返回的结果是成功就执行传入的transform将T值转换成R值返回,

返回的结果是失败或者执行传入的transform发生异常都返回异常。

public inline fun <R, T> Result<T>.mapCatching(transform: (value: T) -> R): Result<R>

返回的结果是成功就组合执行runCatching(transform),transform将T值转换成R值,执行成功就返回R值,执行异常就返回异常。

返回的结果是失败或者执行传入的transform发生异常都返回异常。

recover( )

recoverCatching( )

public inline fun <R, T : R> Result<T>.recover(transform: (exception: Throwable) -> R): Result<R>

返回的结果是成功就返回值,

返回的结果是失败就执行传入的transform处理异常并返回一个值。

public inline fun <R, T : R> Result<T>.recoverCatching(transform: (exception: Throwable) -> R): Result<R>

返回的结果是成功就返回值,

返回的结果是失败就执行传入的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)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值