当前位置: 首页 > 知识库问答 >
问题:

Android@NonNull有用性

卫华奥
2023-03-14

经过一些阅读和类似的问题,我想知道使用@NonNullAndroid支持注释是否有意义。

如果我试图调用一个带有注释为@NonNull的null参数的方法,我可以从androidstudio看到一个非常小的警告。只是一个警告??

那么单元测试呢?我应该用空参数测试这个方法吗?如果我这样做。。。我将得到一个NullPointerException,我的测试将失败。

假设我们是两个开发者。一个在开发API,另一个以各种方式测试API。作为第二个开发人员,我的责任是测试所有东西,以便API是防弹的。这就是单元测试的全部意义,对吗?

那么...第一个开发人员使用@NonNull有什么意义?

如果其他人使用这个带有空参数的应用编程接口...那么应用编程接口将抛出一个NPE。然后他会想:“Urg,那个应用编程接口糟透了...NPE!"他是对的。那个淘气的开发人员没有检查他发送的参数是否为空,应该面对一个非法的参数异常,因为这是他的错,而不是API的错!

我错了吗?

我认为这些注释会强制编译器显示错误,比如试图使用null参数调用methodName(@NonNull Object Object)

好的,谢谢大家的评论。如果可能的话,我想总结一下我在这里面临的“问题”。以抽象的方式。

我写一些代码(一个API,一个库,一个类,无论什么)用私有的内部代码包装提供功能的公共方法

假设这些公共方法将被任何其他人(包括我)使用。他们中的一些人接受的参数永远不能为空,否则一切都会崩溃。

阅读您的评论,我面临以下选择:

  1. 继续使用Java文档支持的契约/注释(@NonNull),其中规定参数不能为null。不要检查空参数(否则IDE会警告我),并以某种方式祈祷我永远不会收到空参数
  2. 同上,但强制执行空检查(即使IDE将警告条件将始终为false),并在收到空参数时抛出IllegalArgumentException,而不是引发NPE
  3. 停止使用契约/注释,使用Java文档警告其他开发人员,并添加对所有参数的手动检查

最后,对于单元测试。。。我知道我不能有防弹代码,但我喜欢尽可能地“猴子测试”我的代码,以防止代码中出现意外行为,并验证流程(我相信这是单元测试的基础)-

共有3个答案

申屠秦斩
2023-03-14

评论可能为时已晚,但迟做总比不做好:)

有一个Traute javac插件,它根据方法参数的注释将空检查插入到生成的字节码中。

下面是一个示例Android项目,它说明了这一点。

白刚洁
2023-03-14

在我看来,您的#2方法是API/库的正确方法。使用注释进行静态分析以防止编译时尝试使用null调用方法,并在运行时使用null检查以在传入null对象时给出有用的异常(并快速失败/防止代码中发生意外情况)。在null检查之前使用//noinspection ConstantConditions指令通知IDE取消显示警告(因为检查null的原因是有效的)。

一个随机的NPE表示库/api作者可能遗漏了一些东西,并且有一个bug没有在他们的代码中处理。

一个IllegalArgumentExcema(或带有问题描述的NPE-在这个实例中使用的异常是一个基于观点的参数)指示调用方在调用方法的方式上犯了一个错误。

然而,最终,在您已经使用@NonNull注释后是否测试null将是基于意见和情况的。

夏俊杰
2023-03-14

它的主要目的是向你的同事提供信息。一个人永远不是大型项目的唯一程序员。使用NotNull告诉其他程序员,函数的约定意味着您永远不能向它发送null,所以他们不会这样做。否则,我可能会做出逻辑假设,调用setFoo(null)将清除Foo,而API无法处理没有Foo的情况。

 类似资料:
  • 问题内容: 我发现不方便之处在于番石榴中的前提条件没有标注注释。考虑以下示例: 因此IDE找不到总是错误的。是否有任何特殊原因为什么不标记此前提条件(即使其参数是使用定义的)。 问题答案: 很抱歉,我们没有在任何地方使用过。为什么?我们尝试添加更多的空检查注释,发现: 添加所有其他注释非常冗长。 这就是我们所需要的。诚然,对于Guava开发人员而言,这比Guava用户更为重要。 似乎遇到了大多数问

  • 我正在使用Intellij13.1.5和Java8 SDK,我已经设置了IntelliJ内置的nullness检查器,以便使用作为我选择的注释。 现在,当我写一个像这样的简单类时 我的下一个猜测是,多个库使用相同的注释名称,可能会出现名称冲突。但不幸的是,警告没有指定包的确切类名。如果是这种情况,一定有某种设置启用隐式注释。 如何在不删除注释的情况下删除此警告?

  • 问题内容: 以下两个代码段之间有什么区别? 它们之间有什么显着差异。在这些情况下进行空值检查的正确方法是什么。 问题答案: 两者是互补的:注解记录了必须为非空的事实,而调用则确保运行时该值不为空。 您应该将两者结合起来,如下所示: 有关的文档可以在这里找到: 可选的类型注释不能替代运行时验证 在类型注释之前,用于描述可为空性或范围之类的内容的主要位置位于javadoc中。通过类型注释,此通信以一种

  • 关键字 nonnull和nullable iOS 9新增关键字: 用于修饰属性或者方法的参数、方法的返回值 nonnull不可为空,等同于_Nonnull和__nonnull e.g. @property (nonatomic, strong, nonnull) UIView *view; @property (nonatomic, strong) UIView *_Nonnull vie

  • null > (Docs) +javax包因此看起来是未来的证明 -是JEE的一部分,而不是JSE的一部分。在JSE中,需要导入其他库。 -静态分析工具不支持(仅运行时验证) (docs) -外部库,而不是包 -自findbugs版本3.x以来已不推荐使用 +用于静态分析(由findbugs和Sonar使用) (docs) +用于静态分析(在findbugs中) -JSR-305在fb邮件列表中显

  • 哪些流操作使用、和拆分器特性?它们在这些操作中如何发挥作用? 我不是问这些标志是什么,这在文档中很容易找到。我在问哪些操作使用它们以及如何使用它们。