【问题标题】:Do you use assertions? [closed]你使用断言吗? [关闭]
【发布时间】:2010-11-15 13:21:08
【问题描述】:

这不是一个真正的“问题”,所以我将其设为 CW。

assert

关键字很棒!

它应该让你对自己编写的代码更有信心,但是,直到今天当我创建一个小测试类(

见鬼!我几乎不使用确实非常有用的记录器,但直到今天我才意识到我不使用断言。

你使用断言吗?如果不是,是什么原因?

【问题讨论】:

  • 那么人们会回答“是”和“否”吗?这有多大用处?关于 SO 的断言有很多很多的答案,也许您应该阅读其中的一些?
  • 您是否在常规编码中使用它们 Neil?

标签: java assert assertions


【解决方案1】:

不,永远不要使用它们。不知道为什么,只是从来没有养成这个习惯。

【讨论】:

    【解决方案2】:

    我倾向于不使用它们,虽然我也不知道为什么。

    如果您进行单元测试,例如使用 nUnit,您显然会一直使用它们来验证您的测试结果。

    【讨论】:

      【解决方案3】:

      早在 90 年代,我就被教导要使用很多断言,它们非常有意义。这是很好的防御性编码。

      但是,我认为这已经被单元测试所取代,单元测试实际上强制代码运行并告诉它在哪里被破坏了。调试断言需要有人实际运行调试代码并查看 ui 或日志。单元测试可以自动执行此操作。

      【讨论】:

      • 在测试期间,老鼠可能不会啃通讯线,玩游戏的人不会耗尽内存,日志文件也不会填满硬盘。当您的程序在生产环境中运行时,这些事情可能会发生。 [Hun 00] 务实的程序员
      • 那么您是否声称调试断言以某种方式解决了这些问题?还是说debug asserts、单元测试等解决不了这些问题?还是说所有的测试都不好,所以不要去做?
      • 我强烈反对这个答案。它没有被取代,它已被补充。单元测试不会取代断言。断言对于避免编程错误非常有用,例如将 null 传递给不接受 null 的方法。它就在那里,对你来说,你的参数不能为空,所以你没有(如果参数!= null)到处都是......
      • @gphillip - 我同意,补充是一种更好的看待它的方式。但是,我坚持我的说法,即自动化单元测试(并且它们必须是好的单元测试)可以告诉您更多关于细微中断的信息。有时调试断言深埋在您从几个级别调用的代码中,因此您在编码或执行特定路径时可能看不到它。你是对的,它就在你的眼前,但前提是你正在看它或执行它。单元测试也不能完全解决这个问题,但两者的使用可能会很好。
      【解决方案4】:

      我一直在使用它们。它们是实践“早早崩溃”理念的好方法,最好是解决断言失败的原因,而不是处理错误/损坏的输出。

      问题是你必须养成一种习惯。我很少在其中看到任何中间立场,人们要么不习惯它并且几乎从不使用它们,要么人们使用它们并且它们在整个代码中被严格地乱扔。你只需要进入注意到“哦,嘿,我在这里隐含假设,让我明确确认它'断言(假设)'”的心态

      【讨论】:

      • 对于我在您的回答中读到的内容,我认为验证会做得更好,因为毕竟断言是要在生产代码中删除的。主要目的是在 beta 产品中进行昂贵的检查。
      • Assert 不应该在生产代码中被删除......它们太有用了,无法理解进程失败的原因(想想 4 或 5 层中的 null 传播,这个 null 来自哪里?) .并且不要让我开始影响性能......
      【解决方案5】:

      我不使用它们。单元测试应该足以测试您的代码。此外,由于默认情况下它们被禁用,因此它们通常被完全忽略。然后他们只是倾向于用无用的断言来混淆你的代码,这些断言可以更好地表示为 cmets。

      如果你真的需要这个,但是,一些库有断言静态方法,你可以调用这些方法,不会被跳过 - 这些也更具可读性,因为 assert 关键字不常见,并且可以立即导致“wtf”时刻,但 Assert.x 方法只是可以追踪的方法。尤其是 Spring 框架,它使用了一个断言库。

      【讨论】:

      • 注释可能已经过时或完全错误,而断言是代码中的契约。我不同意断言会使代码混乱,当然也不同意 cmets 更擅长表达断言。任何运行代码以调试代码的人都应该有断言。我想如果你从不使用它,断言关键字是不常见的,但不可读?同意无论您使用哪种方法进行断言,内置或库都无关紧要。
      • 断言,因为它们默认被禁用,所以与代码 cmets 有相同的问题。它们可能“已过时或完全错误”——因为您必须明确地打开它们,因此,它们并不总是按应有的方式断言,并且在它们本身可能不再相关之前不会注意到它们的失败。跨度>
      【解决方案6】:

      简短回答 - 是的。

      长答案 - 并非总是如此,但经常如此。我通常对错误使用断言,因为我知道我无能为力(在程序运行时)并且实际上并不需要记录。例如 - 如果我必须检查某个值是否超出范围,或者指针是否为 NULL,即使它应该具有某个值。

      对于“解析文件”和“找不到文件”等其他内容,我通常会抛出异常。这样我就可以记录错误并改用一些故障安全文件/方法。

      我非常同意 Falaina 的观点,你真的应该注意这一点——“嘿!我在这里做一些假设”

      【讨论】:

        【解决方案7】:

        我倾向于检查错误情况并抛出异常。原因是我希望始终检查这些条件,即使在生产中也是如此,并且异常提供了对失败条件而不是断言的更轻松处理。

        【讨论】:

          【解决方案8】:

          我使用断言来确保不会在我的代码中引入错误。如果我知道一个值应该在映射中,我会为此断言(使用 assert 关键字)。如果我知道一个参数永远不应该为空,我会为此断言。如果我知道参数可以为空,那么我会检查它并抛出相应的异常。

          我在 Code Complete 或 Effective Java 中读到它 - 断言应该用于检测编程错误 - 异常应该用于处理异常但可能的情况。如果您知道该值不会为空(由合同定义),则无需检查代码中每个方法的空值,但如果值不为空值,则断言也没有什么坏处。仅当您为 VM 指定参数 -ea 时才会启用断言,并且如果禁用,它们不应影响应用程序的性能。

          您也应该使用更多的日志记录:-)。了解何时使用跟踪、调试和信息,并确保记录应用程序所做的一切。当您必须弄清楚为什么某些东西在生产环境中不起作用时,它会让生活变得如此轻松。

          【讨论】:

          • “断言应该用于检测编程错误”完全正确 +1
          【解决方案9】:

          不,我不使用它们。

          我被教导,断言不应该在“生产”代码中使用,并且在我开始使用无论如何我必须删除的东西之前 - 根据我所学到的 - 我坚持使用例外来验证条件。

          【讨论】:

            【解决方案10】:

            我从来没有使用过它们,但是我在调​​试我的最后一个程序时遇到了很糟糕的情况,并且有一次记录了变量为空或不包含我期望的值的情况。一旦我完成了所有工作,我就断言了我的程序成功运行所需的一切。

            【讨论】:

              【解决方案11】:

              Java 的 assert 关键字是半途而废(需要使用 -ea 命令行选项运行程序),所以我发现自己依赖于异常而不是断言。

              【讨论】:

                【解决方案12】:

                在引入单元测试之后,断言的唯一真正用途是将方法的不变量传达给其他程序员。在实际代码中执行此操作比在他们无论如何都会忽略的 cmets 中执行此操作要好得多。很难忽略一个断言!

                【讨论】:

                  【解决方案13】:

                  没有。但是等不及了。我曾经用junit对所有东西进行单元测试,但那是学校,小项目没有压力。我现在在现实生活中,我应该在昨天完成这段代码......

                  【讨论】:

                    【解决方案14】:

                    如果您喜欢断言,您就会喜欢合同。它们基本上是将断言扩展到更多情况的想法。

                    【讨论】:

                      【解决方案15】:

                      是的!总是!在每种语言中,关键字都是我最好的朋友!

                      没有不使用断言的真正理由,它们确保我对输入值和状态所做的基本假设得到支持。

                      如果断言失败,这意味着我需要重新评估我的假设并更新代码以处理我在编写当前修订版时没有想到的新奇输入。有什么不喜欢的?

                      像往常一样,它是一个只有在正确使用时才强大的工具。

                      【讨论】:

                        【解决方案16】:

                        是的,我一直使用断言,基本上每当我做出以下假设时:

                        1. 可以使用相当简单的谓词进行检查。
                        2. 仅仅通过阅读附近的代码显然不是真的。

                        但是,对于可能对性能产生微不足道影响的断言,我使用 D 编程语言标准库中的 enforce 函数而不是 assert。这与assert 基本相同,只是它保持在发布模式。对于更昂贵的断言,我使用assert,它从发布模式构建中剥离。

                        【讨论】:

                          猜你喜欢
                          • 2010-12-23
                          • 1970-01-01
                          • 2010-09-07
                          • 1970-01-01
                          • 2010-11-18
                          • 2011-10-09
                          • 2012-06-12
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多