V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
dramakevinzz
V2EX  ›  问与答

Java 什么时候用 assert,什么时候用 if

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

    第一次实习,看组里的代码有的方法进来是 assert ,有的是 if 来判断方法传入的参数是否有效。 目前对 assert 的理解是当我们 debug 或者启动时带-ea 参数的时候,会对方法传入参数进行判断,所以我理解它是在测试阶段能够进行判断。但是当项目上线的时候就无效了。 if 的话就是我们在任何时刻和阶段都可以对方法的传入参数的有效性进行判断。 现在不太确定我对 assert 和 if 的理解是否正确,以及有点不太确定什么时候用 assert ,什么时候应该用 if 。请问是否有朋友可以帮忙指点一下。

    21 条回复    2022-06-27 23:58:39 +08:00
    cheng6563
        1
    cheng6563  
       57 天前
    没用过 assert
    Mirage09
        2
    Mirage09  
       57 天前
    最简单的方法,看看 git blame ,问一问作者为什么要这么写
    msg7086
        3
    msg7086  
       57 天前
    写测试的时候用 assert 。
    assert 一般意味着不满足 assert 就是程序质量有问题,或者是发生了必须要立刻终止程序的严重事态(比如内存数据被篡改,等等)。

    仅为个人理解。
    cwm165
        4
    cwm165  
       57 天前
    org.springframework.util.Assert

    Spring 也封装过一个 assert 。 你点进源码可以看到,它就是为 if 做了一个封装。
    区别于 org.junit.Assert 只是在测试代码中使用。

    所以不要看到同名的类就感到疑惑,还是要看一下它的内部实现,不过这对第一次实习的朋友来说也不是大问题,以后看的多了就明白了。

    至于用 assert 还是 if ,看心情,或者和团队统一,Spring assert 就是 if 的一个封装,不喜欢大段 if 那就大段 assert /doge
    billlee
        5
    billlee  
       57 天前 via Android
    如果你相信按照设计,某个方法收到的参数必定符合某个约束,那就用 assert. 这样在开发过程中如果代码逻辑有问题违反了约束,酒就可以捕获到
    falsemask
        6
    falsemask  
       56 天前
    @cwm165 op 说的 assert 应该不是你说的 assert ,是断言 assert
    dramakevinzz
        7
    dramakevinzz  
    OP
       56 天前
    @Mirage09 我 mentor 在 review 的时候,有的时候会把我写的 assert 改成 if ,有的时候会把 if 改成 assert ,说让我自己体会下什么时候用 assert ,什么时候用 if ,但是我没体会出来,又不是很敢打扰他,就来论坛问问各位前辈。
    @msg7086 那我目前的想法时,在企业级应用中应该都是有部门来严格判断恶意用户的侵入性行为吧,那上下游服务中我们的参数真的有可能会出现严重违反规定的情况存在吗?所以就感觉 assert 不是很必要,应该都用 if 来判断,当参数无效的时候应该直接退出方法或者返回相应类型的空。不知道我的看法对不对。
    @falsemask 对的,这里是指断言 assert ,我没有说清楚。
    tairan2006
        8
    tairan2006  
       56 天前
    assert 代码 release 之后无效,只是用来调试的。

    说白了,就是可能会有问题就 if ,一定不会出现问题(除非有 bug )就 assert.
    Mirage09
        9
    Mirage09  
       56 天前
    @dramakevinzz
    体会个什么玩意,传功么…
    直接问他吧,不要频繁骚扰人不意味着不问问题,更何况这是你的第一个实习
    msg7086
        10
    msg7086  
       56 天前
    @dramakevinzz 哦,我也误解了,以为你说的是 JUnit 之类的 assert 。
    Java 自己的 assert 断言说实话我代码读到现在还没有见人使用过。(也可能是我读得少……
    lzrainchen
        12
    lzrainchen  
       56 天前
    Java 中的 assert 关键字中文翻译为"断言",if 关键字为"分支跳转"。这两个的确不是同一个"东西"。如果你领导真的让你思考体会,你真的应该仔细体会一下。以下是我的理解:assert 在于检测当前状态必须为某个状态,而 if 在于控制状态之间的流转。这就是他们最本质的不同。我用大白话再解释一下:程序就是一个状态机,在某一个时刻状态机只有一个确定的状态,这个时候我们可以 assert 它是一个什么状态,如果不是此状态就说明程序不符合我们的设定,可能有错。而 if 条件在于控制状态机的流转,就这样。其实我们想解释清楚一件事是很困难的哪怕再不起眼的小事。仔细思考,仔细体会
    adoal
        13
    adoal  
       56 天前
    举个栗子:过程 A ,从界面获取用户输入;过程 B ,检查用户输入的格式正确性;过程 C ,拿用户输入调用后端业务。
    业务逻辑是按顺序调用 A 、B 、C 。

    过程 B 里判断输入格式是否正确,用 if ,因为不对的格式是用户输入的,程序不可控,遇到了不是程序的错。

    过程 C 里要再检查一遍用 assert ,因为这里数据不是直接来自不可控的用户输入,这是程序员可控的环节,格式再不对就是 B 写错了,写对的程序执行到这里不应该有不对的数据。
    liprais
        14
    liprais  
       56 天前 via iPhone
    assert 就是不符合就要 panic 不能往下走了
    if 就是不符合下面还有
    yolee599
        15
    yolee599  
       56 天前 via Android
    assert 就是开发的时候使用的,上线的时候失效,可以减少对运行效率的影响,并且确保生产环境中不会出现这种问题。通常用于入参合法性判断,比如入参空指针。
    litmxs
        16
    litmxs  
       56 天前 via Android
    assert 用于内部接口,输入的数据在开发阶段可控,调用者是内部的开发者,如果不满足 assert 条件,说明是开发人员编码问题,这时候应该把整个程序都干掉,因为这是编码错误,应该要及时暴露出来。


    if 用于外部接口,开发阶段没办法知道会传入什么样的数据,需要校验然后返回相应错误提示(错误码、日志、异常等),然后让程序重试或者安全退出。
    sun1993
        17
    sun1993  
       56 天前
    写 UT 的时候用 assert ,其余情况不考虑,反正我是这么干的
    dramakevinzz
        18
    dramakevinzz  
    OP
       56 天前
    @lzrainchen
    @adoal
    @liprais
    @yolee599
    @litmxs
    大致明白了,还是要结合业务场景去判断,比如上游数据应该是从内部服务中获取的,这种就应该用 assert ,因为内部服务要确保数据的合理性和正确性,但是如果对于由外部不可控因素的数据就应该是用 if ,那我再结合代码看下吧,谢谢各位
    dramakevinzz
        20
    dramakevinzz  
    OP
       55 天前
    @liprais 感谢,目前有了更多理解
    agagega
        21
    agagega  
       45 天前
    assert:这个错误不应该出现,出现就表示程序写错了
    exception:这个错误有可能出现,但可能性不大,并且我也没办法直接解决
    if:这个错误很可能出现
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   4285 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 06:29 · PVG 14:29 · LAX 23:29 · JFK 02:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.