V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
jeesk
V2EX  ›  Kotlin

kotlin 没有受检异常真太难顶了。吐槽

  •  
  •   jeesk · 2 天前 · 2969 次点击
    1. 比如我要统一处理登陆失败和网络错误。

    如果是在 java 里面直接在方法里面抛出 2 个异常即可。 但是在 kotlin 里面必须

    	val runResult = runCatching{
           HttpResponse(it.isSuccessful,it.code,it.message)
        }
        if(runResult.isFailure){
           when(moveFileAgain.exceptionOrNull()){
            // 单独处理异常
              
           }
        
        }
        // 还有写一些(这里请求成功了)
        if(result.code == 404){
           return runResult.getOrDefault()
        }
          if(result.code == 401){
            // 认证失败了
           return runResult.getOrDefault()
        }
       
    
    

    如果是在 java 里面就再简单不过了,直接定义两个异常,全局处理. 受检查异常是真的爽。 特别是在嵌套请求,1 个 api 要请求好几次的情况。

    这么说吧。 这里面的很多常见使用 java 来写代码可能要简单的多。 哪有这么多的破事。

    大佬们有什么办法处理这种事情, 我的要求就是登陆 401 或者有异常直接返回就是了。kotlin 实在是太繁琐了。

    41 条回复    2024-10-12 20:08:05 +08:00
    RicardoY
        1
    RicardoY  
       2 天前
    没有看懂这和受检异常的关系是什么,你用 kotlin 不一样可以抛出自定义异常吗
    winterbells
        2
    winterbells  
       2 天前 via Android
    同样看不懂你要什么

    val exception = Exception("401")

    if (xxx) throw exception
    zhwguest
        3
    zhwguest  
       2 天前
    我猜 op 的意思是在收到非 2xx 状态码的时候抛出异常。

    但是这个是 API 的特性,而不是语言的特性。比如 okhttp ,ktor 等。api 一般都有选项可以设置什么时候抛出异常,什么时候认为是正常的 response 。
    sagaxu
        4
    sagaxu  
       2 天前
    unchecked exception 和 checked exception ,唯一区别就是 unchecked 可以隐式想上传递,checked 必须包在 try 中或者在方法签名中显式声明。

    调用链路的上层,IDE 会提示哪些 checked exception 没有处理,而 unchecked exception 你无法知道可能会抛出哪些异常。所以 Kotlin 使用 @Throws(IOException::class)把信息包含进去。

    所以 OP 在 Kotlin 中同样可以“直接定义两个异常,全局处理”。但很遗憾,他用 runCatching 吃掉了异常,然后手动处理,把 Kotlin 写出了 Go 的感觉。
    superchijinpeng
        5
    superchijinpeng  
       2 天前   ❤️ 5
    有没有可能是你不会用
    hwb
        6
    hwb  
       2 天前
    有没有可能是你不会用
    chendy
        7
    chendy  
       2 天前
    看到标题:怎么会有人喜欢 Checked Exception 呢?
    看完内容:果然说的不是 Checked Exception

    代码封装或者风格的问题,和语言不能说毫无关系只能说毫无关系
    yuhuazhu
        8
    yuhuazhu  
       2 天前
    自己定义一个方法统一判断然后抛出异常,
    然后 BaseViewModel 的写一个协程的扩展函数去处理异常,
    比如你给这个函数起名字叫 runCatching
    Vaspike
        9
    Vaspike  
       2 天前
    java 能做的 kotlin 一定能做
    jeesk
        10
    jeesk  
    OP
       2 天前
    @Vaspike 能帮我强制处理异常不? 我嵌套 10 几个函数, 如果没有受检查异常, 每个都要单独判断. 处理工作量大幅增加. 现在只能将异常封装在函数返回值里面.
    location123
        11
    location123  
       2 天前
    使用 OkHttp 的情况下
    只是判断这个请求的 http 请求错误 可以判断异常父类是否是 HttpException
    inline fun <T : HttpService, R> T.execute(block: T.() -> BaseResponse<R>): Result<R> {
    return try {
    val response = block()
    if (response.success) {
    Result.Success(response.data)
    } else {
    //内置协议错误
    // Result.Fail(response.header.code.toInt(), response.header.msg, false)
    }
    } catch (e: HttpException) {
    //http fail
    } catch (e:CancellationException){
    //cancel
    } catch (e: Exception) {
    //other fail
    }
    }
    网络请求全部走 HttpService 的扩展函数

    第二种
    在协程的顶级作用域里面统一处理
    chendy
        12
    chendy  
       2 天前
    @jeesk 再封装一层,异常情况直接甩异常出来
    maninfog
        13
    maninfog  
       2 天前   ❤️ 1
    Java 能抛的异常,Kotlin 也能抛。只是说 Kotlin 对于 Checked Exception (CE) 没了编译器的保护,up 觉得不太安全?
    关于 Kotlin 取消 CE ,褒贬不一,想起这个文章: https://www.yinwang.org/blog-cn/2017/05/23/kotlin
    jeesk
        14
    jeesk  
    OP
       2 天前
    @chendy 目前就是用 runtrycatch 了, 如果有异常, 直接将异常回填到返回值了。
    jeesk
        15
    jeesk  
    OP
       2 天前
    @maninfog 某些情况下合理使用受检查异常, 能省下很多的代码。
    cmdOptionKana
        16
    cmdOptionKana  
       2 天前
    Checked Exception 与 Go 的 error 貌似有共通的思想。
    githmb
        17
    githmb  
       2 天前
    《提问的艺术》
    jeesk
        18
    jeesk  
    OP
       2 天前
    @githmb 我这不是吐槽吗?
    AoEiuV020JP
        19
    AoEiuV020JP  
       2 天前
    没懂,throw, try, catch, 哪个是 kotlin 办不到的,效果明明和 java 一样,
    你要不试试用 java 写了再一键转成 kotlin 看看再说有什么问题,
    yazinnnn0
        20
    yazinnnn0  
       2 天前
    这跟嗑特灵有啥关系
    githmb
        21
    githmb  
       2 天前
    @jeesk 吐槽也要吐槽对啊,什么叫”kotlin 里面必须“,然后贴一段排版差注释差的代码,不用 Result 风格不就行了? Kotlin 哪里不能抛异常了?
    qwwuyu
        22
    qwwuyu  
       2 天前
    @jeesk 受检查异常并不能能省下代码.最多是忘记捕获某个特定的异常,导致程序异常.
    yuezk
        23
    yuezk  
       2 天前
    感觉是用法问题,还在用 Java 的语言习惯来写 Kotlin
    Leviathann
        24
    Leviathann  
       2 天前
    use typed error
    niubilewodev
        25
    niubilewodev  
       2 天前
    看下来没看懂。
    kotlin 只是去掉了 checked exception 必须要显式处理的特性。
    该抛什么错还是一样会抛什么错。
    你在 java 怎么 catch 的,在 kotlin 一样能 catch 到。
    little_cup
        26
    little_cup  
       2 天前
    @githmb 我反而觉得题主很懂啊,你要是正儿八经提个问,回帖能有现在的零头不
    jeesk
        27
    jeesk  
    OP
       2 天前
    @niubilewodev 是能够 catch 到, 但不是受检异常, 如果忘了就嗝屁了.
    WebKit
        28
    WebKit  
       2 天前
    感觉是你不会用,或者是你编码习惯的问题。除了成功。其他都是异常情况,必须要处理异常情况,不存在忘记的情况
    superchijinpeng
        29
    superchijinpeng  
       2 天前
    @jeesk #27 为什么会忘记,测试肯定会覆盖到
    zed1018
        30
    zed1018  
       2 天前
    我反而讨厌 checked exception ,正常需要处理的肯定会 catch ,不需要处理的就像让他 throw 就完事了,遇到 checked 的还要 catch 以后转 runtime ,当然,我是后端有框架兜底策略。
    jeesk
        31
    jeesk  
    OP
       2 天前
    @superchijinpeng 你测试一定能测试出所有的 BUG.


    场景不一样, 我觉得很多人 get 不到我的点. 如果支持受检测异常, 异常处理只需要在调用处处理异常即可, 但是 kotlin 没有受检异常, 可能会漏掉. 难道我不知道 kotlin 一样能使用 try catch 吗?

    我说没有受检异常, 你跑来告诉我可以使用 try catch . 这是一个东西吗?
    然后我说使用 try catch 可能会漏掉, 然后你告诉我测试肯定会覆盖.
    unco020511
        32
    unco020511  
       2 天前
    这个是你真的不会用了,和语言无关啊
    superchijinpeng
        33
    superchijinpeng  
       2 天前
    @jeesk #31 你可能会忘,IDE 不会,.try 会自动帮你补全所有情况
    githmb
        34
    githmb  
       2 天前
    就问你一个问题,空指针异常是不是 Java 程序出问题最多的异常,为什么空指针异常要搞成运行时异常,让这么多人漏掉?
    jeesk
        35
    jeesk  
    OP
       2 天前
    @githmb 不想回答你. 能不能不要问牛答马 ?
    yooomu
        36
    yooomu  
       2 天前
    没看懂你的诉求,checked exception 和 unchecked 的唯一不同就是编译器强制你捕获它。所以是因为 kotlin 编译器没有强制你捕获让你没有安全感吗
    catamaran
        37
    catamaran  
       2 天前
    受检异常,这是谁起的名字,我第一次看到
    Mystery0
        38
    Mystery0  
       2 天前
    java 里面怎么全局处理?用
    ```
    Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
    //fuck something
    });
    ```
    ?

    那 kt 也没阉割这个啊,kt 不照样可以写这个
    SoloCompany
        39
    SoloCompany  
       2 天前
    我来教你怎么在 java 里面像 kotlin 那样不用忍受反人类的 checked exception
    https://stackoverflow.com/questions/11584159/is-there-a-way-to-make-runnables-run-throw-an-exception/53456631#53456631
    wwalkingg
        40
    wwalkingg  
       2 天前
    1. 题主不熟悉 Kotlin
    2. 题主觉得想要语言强制要求处理受查对象。这个特性本身有争议。个人觉得 Kotlin 这样很好,反正最后有一个兜底的异常捕获就行。
    Belmode
        41
    Belmode  
       2 天前 via Android
    无力吐槽
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2929 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 14:13 · PVG 22:13 · LAX 07:13 · JFK 10:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.