开发者社区> 问答> 正文

您是否应该在生产代码中使用assert语句断言不为null?

我已经看到了这个问题,但是关于assert关键字的用法还有其他一些问题。我正在和其他一些编码员讨论使用assert。对于此用例,有一种方法可以在满足某些先决条件的情况下返回null。我编写的代码调用该方法,然后断言它不会返回null,并继续使用返回的对象。

例:

class CustomObject {
    private Object object;

    @Nullable
    public Object getObject() {
        return (object == null) ? generateObject() : object;
    }
}

现在想象一下我是这样使用它的:

public void useObject(CustomObject customObject) {
    object = customObject.getObject();
    assert object != null;
    // Do stuff using object, which would throw a NPE if object is null.
}

有人告诉我应该删除assert,不要在生产代码中使用它们,而只能在测试中使用。真的吗?

问题来源:Stack Overflow

展开
收起
montos 2020-03-21 23:58:38 2826 0
1 条回答
写回答
取消 提交回答
  • 使用Objects.requireNonNull(Object)了点。

    检查指定的对象引用是否不为null。此方法主要用于在方法和构造函数中进行参数验证,[...] 在您的情况下,这将是:

    public void useObject(CustomObject customObject) {
        object = customObject.getObject();
        Objects.requireNonNull(object);
        // Do stuff using object, which would throw a NPE if object is null.
    }
    

    此功能用于您提到的目的,即显式标记不为null的内容;也正在生产中。这样做的最大好处是,您可以确保在不应该出现空值的地方找到空值。调试由空值传递到不应该传递的地方引起的问题时,您将遇到麻烦。

    另一个好处是与相比,空检查的额外灵活性assert。虽然assert是用于检查布尔值的关键字,但它Objects.requireNonNull(Object)是一个函数,因此可以嵌入到代码中,更加灵活和易读。例如:

    Foo foo = Objects.requireNonNull(service.fetchFoo());
    
    // You cannot write it in on line.
    Bar bar = service.fetchBar();
    assert bar != null;
    
    service.foo(Objects.requireNonNull(service.getBar()));
    
    // You cannot write it in on line.
    Bar bar = service.getBar();
    assert bar != null;
    service.foo(bar);
    

    请记住,这Objects.requireNonNull(Object)是专门用于对null进行assert广义检查的地方。assert在这方面的目的略有不同,即主要是测试。必须启用它,因此您可以启用它以进行测试并禁用它以进行生产。无论如何,请勿将其用于生产代码。它可能会使用于测试的不必要和复杂的验证减慢应用程序的速度。使用它也可以将仅测试检查与用于生产的检查分开。

    查阅官方文档以获取有关的详细信息assert

    回答来源:Stack Overflow

    2020-03-22 00:01:03
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载