Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是Java断言的过度使用吗?_Java_Assert - Fatal编程技术网

这是Java断言的过度使用吗?

这是Java断言的过度使用吗?,java,assert,Java,Assert,我正在努力掌握Java中assert关键字的用法。据我所知,正确的情况是验证应该始终正确的事情 然而,我担心我过度使用了资产 以下是一个示例: private BodyParams() { assert revokedDoc != null : "revokedDoc must not be null"; assert revokedDoc.getStatus() == DocumentStatus.Revoked : "document is not revoked";

我正在努力掌握Java中
assert
关键字的用法。据我所知,正确的情况是验证应该始终正确的事情

然而,我担心我过度使用了资产

以下是一个示例:

private BodyParams() {
    assert revokedDoc != null : "revokedDoc must not be null";
    assert revokedDoc.getStatus() == DocumentStatus.Revoked : "document is not revoked";
    assert !isBlank(revokedDoc.getDocType()) : "docType should not be blank";
    assert revokedDoc.getIssuedDate() != null : "doc should have issue date";
    assert revokedDoc.getSendingOrg() != null 
            && !isBlank(revokedDoc.getSendingOrg().getName()) 
            : "sending ord should exists and name should ne populated";

    if (registeredUser) {
        assert revokedDoc.getOwner() != null 
                && !isBlank(revokedDoc.getOwner().getFirstName()) 
                : "owner should exists and first name should be populated";

        this.ownerFirstName = revokedDoc.getOwner().getFirstName();
        this.docUrl = Application.PUBLIC_HOSTNAME 
                + controllers.routes.DocumentActions.viewDocument(
                    revokedDoc.getId()
                ).url();

    } else {

        this.ownerFirstName = null;
        this.docUrl = null;

    }

    if (revokedDoc.getStatus() == DocumentStatus.Available) {
        assert !isBlank(revokedDoc.getFriendlyName()) 
                : "friendly name should not be blank for picked-up docs";

        this.friendlyName = revokedDoc.getFriendlyName();

    } else {
        this.friendlyName = null;
    }

    this.docType = revokedDoc.getDocType();

    this.issueDate = revokedDoc.getIssuedDate();

    this.issuerName = revokedDoc.getSendingOrg().getName();
}
在本例中,假设revokedDoc字段来自数据库,并且在插入时执行了正确的验证。这些断言验证了这一假设。这是不是太过分了


编辑:我应该提到,这只适用于开发代码。断言将不会在生产中启用。我使用断言来确保已知的数据在开发过程中表现良好,这些数据来自生产中的可信来源这可能是一个自以为是的问题。但是,我会选择以下几点来决定:

  • 如果这个方法暴露于外部世界(通过接口、JAR文件、用户输入字段或任何您可以从不在您控制范围内的源获取输入的地方),那么我应该有一个有效的实际检查,这将导致异常
  • 我是否依赖断言来正确执行代码?如果是的话,我不应该。在运行时,断言将被禁用
  • 这个断言总是正确的吗?如果是的话,我会在关闭的情况下使用它进行调试吗?然后是的,使用断言代替代码注释。当出现问题时,启用断言并找出问题所在

    您需要考虑两个场景:<强>开发代码< /强>和<强>生产代码< /强> ./P> 默认情况下,Java的<代码> AsStury< /Cord>语句被禁用(并且通过检查通过将代码> > EA< /COD> >到VM而启用的全局静态标志只增加很少的开销,我不考虑这个开销,因为它帮助您在开发阶段早期发现问题。(假设您在开发环境中启用了断言)


    另一方面,您会说“…插入时执行了正确的验证…”-那么,您如何知道数据库中的值没有同时更改?如果安全性对您的系统很重要(我只是假设它会更改),一个基本模式是,您不能信任从外部获得的任何东西。这意味着,验证从数据库读取的值-但在这种情况下,
    assert
    不是合适的工具。为此,请使用正常的验证代码和异常。
    assert
    非常有用,以执行应该始终为真的内部e库或模块。它旨在验证代码中的不变量(控制流、内部等),使用它强制正确使用代码是一个坏主意(您有例外)

    因此,您的公共接口永远不应该基于断言:当您有一个公共方法并且想要检查输入参数时,通常最好抛出一个
    IllegalArgumentException

    有一些关于资产的好文档


    在您的示例中,我认为您应该使用异常而不是断言。对来自数据库的数据执行一些有效性检查(即使已对输入进行了验证)不是一个坏主意但断言可能在生产代码中被禁用,您必须考虑如何处理这种格式错误的内容。

    它看起来不正确。为了简化,可能会出现两大类问题,需要检查变量的有效性:

    • 您的方法接收或使用的参数可能不是您期望的参数,并且您的方法应该进行适当的参数检查,并抛出
      IllegalArgumentException
      NullPointerException
      或其他任何需要的参数。例如:客户端代码传入了null参数,您无法控制该c颂歌
    • 您的方法使用了一些类内部构件,您应该进行适当的单元测试,以确保这些内部构件始终是一致的,并且您的方法可以在不进行额外检查的情况下使用它们
    在您的情况下,创建
    revokeDoc
    对象的方法应确保该对象在创建后处于有效状态,并采取适当的措施,否则,例如抛出异常并回滚任何更改。这样,您的
    BodyParams
    方法就可以使用该对象,而不必使用所有会使代码混乱的断言错误的时间:如果
    revokeDoc
    不一致,则采取行动可能为时已晚,应该更早检测到


    相关帖子:

    根据面向对象的方法,最好的做法是检查你收到的参数。并为其他人创建定期检查。在你的情况下,你应该得到这样的结果:

    private BodyParams(revokedDoc)
    [...]
    asserts of the params
    
    if(isBlank(revokedDoc.....)
    

    所有的资产看起来都很好,这是确保方法所有东西都能运行的方法。但它们应该是帮助您了解发生了什么错误,而不是让您的程序正常工作。

    如果您明确希望您的程序在测试期间失败,这并不是过火。当然这取决于您将要做什么,但不成功确保所有操作都正确非常重要,我想您的应用程序最好能更“优雅”地失败,即使用自定义异常或填充默认值。就验证数据库中的数据而言,该数据上的所有操作都在该应用程序的控制下。假定插入和更新数据将正确处理。任何不正确的处理都是我们将要修复的错误。在本例中,我只是简单地断言文档类的不变量。您认为我应该在这种情况下使用异常吗?这可能是
    自以为是的答案
    发挥作用的地方;)我很可能会使用异常,尤其是从数据库(或任何其他数据源)读取数据时。我不知道你使用的是哪种数据库系统,但你永远也不能