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

你在 Java 里用 try-catch 多不?

  •  
  •   NoKey · 159 天前 · 4854 次点击
    这是一个创建于 159 天前的主题,其中的信息可能已经有所发展或是发生改变。

    为了避免可能出现的异常

    我们这里大部分方法都用 try-catch 括起来

    看起来很难看啊。。。

    比如,接收页面传入的整数,传过来是字符串,我们需要用数字的时候,就会 Integer.valueOf()

    但是,写页面的人不是同一个,也可能经常换,也可能不同项目组

    虽然有文档,但是,不能确保一定会传入整数

    为了在可能出问题的时候不会出问题而背锅,我们就需要用上 try catch

    有大佬会说使用前验证参数

    有时候参数很多,每个都去验一次么?

    各位大佬有啥好方法么?😄

    44 条回复    2020-05-13 18:20:09 +08:00
    FanError
        1
    FanError   159 天前
    现在我都是 throw RuntimeException 了,然后全局异常捕获,统一返回报错信息
    luckyrayyy
        2
    luckyrayyy   159 天前
    楼上+1,直接抛,全局补
    zhuangzhuang1988
        3
    zhuangzhuang1988   159 天前
    <Java8 实战>里这样扯过 P217
    public static Optional<Integer> stringToInt(String s) {
    try {
    return Optional.of(Integer.parseInt(s));
    } catch (NumberFormatException e) {
    return Optional.empty();
    }
    }
    然后再应用

    PS: 其实 C#很早就有函数 tryParse https://docs.microsoft.com/en-us/dotnet/api/system.int32.tryparse?view=netframework-4.8
    yjxjn
        4
    yjxjn   159 天前
    @luckyrayyy 这个全局补怎么说?比如调用某工具类里方法全部抛出异常,然后再调用的 Controller 里面接么?能详细说一下吗?
    luckyrayyy
        5
    luckyrayyy   159 天前
    @yjxjn ExceptionHandler 注解
    asd123456cxz
        6
    asd123456cxz   159 天前
    @yjxjn 如果是 Spring 项目,可以新建一个异常处理类,使用 @ControllerAdvice 注解,默认使用 AOP 构造出针对全部 controller 的代理类,全局处理异常。不过自己写一个切面部分地处理也可以,顺便把日志统计也做了
    Jrue0011
        7
    Jrue0011   159 天前
    Spring MVC 的话,Controller 加 Validated 注解,MVC 本身参数绑定自带的校验再加上校验注解,支持简单参数、Form 对象和 RequestBody 对象,进入方法前入参就校验完了,ControllerAdvice 捕获校验异常统一返回 SmartValidator 格式化后的校验结果,还支持国际化。。。
    superrichman
        8
    superrichman   159 天前 via iPhone
    所有传入的参数都要验证。可以搜搜 java form validation,不需要自己写一堆 try catch
    Jrue0011
        9
    Jrue0011   159 天前
    @Jrue0011 另外这样校验也支持分组。。就是入参是同一个 bean 类,这个接口只校验某几个属性,另一个接口校验另外一些属性
    limuyan44
        10
    limuyan44   159 天前
    全靠全局捕获,自己基本不会用,项目里每个 controller 里面写过 trycatch return 一个自定义 response 我都感觉这帮人没正经学过 spring mvc,框架安排的明明白白的,不需要自己做这种丑陋的写法
    optional
        11
    optional   159 天前 via iPhone
    lombok
    loryyang
        12
    loryyang   159 天前
    Spring MVC 直接支持了啊,都不需要你来处理,包括类型和空判断
    zhuawadao
        13
    zhuawadao   159 天前
    araaaa
        14
    araaaa   159 天前
    let it crash
    xuanbg
        15
    xuanbg   159 天前
    一般都是直接抛,然后全局捕获。只有确定需要处理的异常,才 try/catch 起来自己处理掉异常。譬如处理队列消息的时候,异常了要写回死信队列,以免丢消息。
    paragon
        16
    paragon   159 天前
    关键字 JSR349 ControllerAdvice
    mawerss1
        17
    mawerss1   159 天前 via iPhone   ❤️ 1
    强烈反对上面的把异常 catch 掉返回空值的做法,破坏了语义甚至可能产生一些发现不了的逻辑问题,如果非要 catch,建议再向上层抛出一个定义异常
    oneisall8955
        18
    oneisall8955   159 天前 via Android
    这种运行时的,不用管吧,前端传过来错误的,不按照接口定义写,肯定是对方的问题,不是我的问题为啥要管呢
    sagaxu
        19
    sagaxu   159 天前 via Android
    crash early
    crash often
    yanyueio
        20
    yanyueio   159 天前
    和楼上观点大概类似:

    * Java Core: 避开 checked 异常这类编译时就强迫你处理的异常,其他异常 let crash 。
    * 框架: 比如 Spring 系,全局处理,而且搭建架子的负责人应该会提前制定好规范&模板了。

    至于说入参的检验,那要看大家约定的是依靠返回值(json 对象或者其他)来判断还是是依靠抛异常来协商了(类似防御式编程类的官样话),这太灵活了,还是看团队如何约定的。
    orm
        21
    orm   159 天前
    目前我用 try catch 最多的就是在一些定时任务上,避免执行过程终端
    cshijiel
        22
    cshijiel   159 天前
    1. Bean Validation(JSR380)
    2. @ControllerAdvice
    3. BizRuntimeException(建议)
    xiaofan2
        23
    xiaofan2   159 天前
    @cshijiel BizRuntimeException 是啥??
    ganning
        24
    ganning   159 天前
    @Validated 可以了解一下这个注解
    kanepan19
        25
    kanepan19   159 天前
    有事务的地方抛异常, 没事务的地方都抓,抓了把异常放到 resultMsg 放到 result 里返回。
    全局异常肯定有,个人不喜欢随便抛。
    chendy
        26
    chendy   159 天前
    工具类里写挺多的,吃掉一些不可能出现的 checked exception (然后抛一个自定义 unchecked exceptoin ),比如加密算法没找到,编码未找到这种…
    yeqizhang
        27
    yeqizhang   159 天前 via Android
    不是用户填的东西的话,没必要,和前端调通了之后一般没有问题,有问题也是要找为啥数据会错。
    如果是用户填的,前端先检验,然后后端也要做检验或者捕获异常,我遇到测试测接口直接传不符合的数据然后提 bug 的
    mosliu
        28
    mosliu   159 天前
    用 common lang3 的 NUmberUtils 的 toInt 不行么? 错误的转出来个默认值 检查直接返回错误。
    aitaii
        29
    aitaii   159 天前
    @xiaofan2 继承 RuntimeException 的自定义业务异常,ExceptionHandler 里处理异常信息
    sunxiansong
        30
    sunxiansong   159 天前
    插一下嘴。。

    之前写 java,try catch 用的不多,反正有毛病都抛出去。

    现在写 go, 各种
    ```go
    if err != nil {
    return err
    }
    ```
    遇到返回结果有 error 的都要这么来一下,复杂点的函数能来好几次

    觉得 java 的话,对于需要特别识别的错误,可以检查下,不然就直接抛出吧,大部分正常流程能走通就行

    有些函数声明的异常甚至几乎不会出现,追求完善的错误处理覆盖是不现实的,还不如完善错误监控处理机制,避免隐式错误处理、错误遗漏,定期的检查错误情况再完善代码

    如果只是不喜欢 try catch 风格,那自己搞一套错误-结果返回方案就行
    EminemW
        31
    EminemW   159 天前
    我有个疑问,这个抛异常会影响性能吗,之前不知道在哪里看过不要随便抛异常。。我的做法的是 return Result.error(code, msg);
    chanchan
        32
    chanchan   159 天前 via Android
    很多地方需要写,但是懒得写😐
    lihongming
        33
    lihongming   159 天前 via iPhone
    拿异常当日常反馈的路过。

    只要数据不合格就抛异常出去,调用方不 try catch 怎么活啊?
    yukiloh
        34
    yukiloh   159 天前 via Android
    以前自己喜欢扔,后来看到哪里说能抓尽量当下抓,不能的再扔,给搞迷糊了
    purensong
        35
    purensong   159 天前
    定义一个 @ControllerAdvice 修饰的全局异常处理类,实现多个方法加上 @ExceptionHandler(value = Exception.class)
    注解,value 是 Exception 的子类,例如要检查必须的字段传入,用 MethodArgumentNotValidException,具体的字段不能为空用 @NotNull 注解。
    这是通用的异常处理,如果还有业务异常,需要自定义异常类,我习惯直接在代码里抛出自定义异常,也都交由全局异常类去特殊处理
    purensong
        36
    purensong   159 天前
    可以说代码里 try catch 可能都是连接消息关闭,文件不存在这些代码,很少会出现类型检查这种低级别的捕获,这种检查代码大量存在,而且级别较低,不会有出现异常后的处理,基本就是报错提示到前端就没有了。
    pabno
        37
    pabno   159 天前
    1. 从项目整体质量的角度出发,接口约定就应该遵守,如果不是强制约束,即使后端可以兼容这种数据格式,前段指不定也会因为数据格式的不一致而引发新的问题,提前暴露问题会减少修正错误的成本

    2. 后端参数验证可以使用校验框架写表达式自动校验,然后统一捕获校验异常返回统一数据
    xiangyuecn
        38
    xiangyuecn   159 天前
    转换成 int 时,返回 Integer 类型,要么返回一个数要么,返回一个 null,拒绝使用 try catch

    byte 统一用 short 类型,拒绝负数 ( doge
    vwym
        39
    vwym   158 天前
    web 项目就直接抛出去全局处理了,参数验证可以考虑用 Validations 注解完事。
    不做 try catch
    Mystery0
        40
    Mystery0   158 天前 via Android
    @EminemW 确实有一点影响,不过照你的这样子返回 Result.error(code, msg),调用深了以后,每一层都要去做执行结果的判断,写着写着就变成手写 Java 的异常处理机制了
    NoKey
        41
    NoKey   156 天前
    @pabno 遵守接口约定,按照文档规定写代码,这个要看公司文化,强制执行的的,谁出问题问责谁这没问题,但是有些公司,会把涉及的人都弄出来批一次。。。什么,他传错了参数?他传错参数,你代码不会鉴别?你代码就死在里面了?你这是什么代码?有些公司强绩效,为了不扣分,谨小慎微,尽量避免问题出在自己这一块😂
    pabno
        42
    pabno   153 天前
    @NoKey 我的意思就是提前校验,让他不能传约定外的参数类型。这种如果客户端传了约定外的类型,那在测试阶段就要把这个问题暴露出来
    notwaste
        43
    notwaste   147 天前
    可以去看下 Hibernate validator
    xinQing
        44
    xinQing   132 天前
    Hibernate validator 校验参数;抛出异常,全局处理。
    同一楼、二楼
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4552 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 56ms · UTC 09:00 · PVG 17:00 · LAX 02:00 · JFK 05:00
    ♥ Do have faith in what you're doing.