安卓@NonNull实用性

经过几次阅读和像这样的问题,我想知道使用Android支持注释是否有意义。@NonNull

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

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

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

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

如果其他人将此 API 与空参数一起使用...然后API会抛出一个NPE。然后他会想:“哎呀,那个API很糟糕...NPE!“他会是对的。那个顽皮的开发人员没有检查他发送的参数是否为空,应该面对一个非法的ArgumentException,因为这是他的错,而不是API的错!

我错了吗?

我以为这些注释会强制编译器显示诸如.attempting to call methodName(@NonNull Object object) with null parameter

更新 1

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

我用提供功能的公共方法包装的私有内部代码编写一些代码(API,库,类等)。

假设这些公共方法将被其他人(包括我)使用。他们中的一些人的论点永远不能为空,否则所有的地狱都会松动。

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

  1. 继续使用 Java 文档支持的契约/注释 ()。不要检查空参数(否则IDE会警告我),并且以某种方式祈祷我永远不会收到空参数;@NonNullparameter must not be null
  2. 与上面相同,但强制执行空检查(即使IDE会警告),并在我收到空参数的情况下抛出而不是导致NPE;condition will always be falseIllegalArgumentException
  3. 停止使用合约/注释,使用Java Doc警告其他人开发人员,并对所有参数进行手动检查。

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


答案 1

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


答案 2

在我看来,您的#2方法是API /库的正确方法。使用用于静态分析的注释可防止编译时尝试调用具有 null 的方法,并在运行时使用 null 检查来提供有用的异常(并快速失败/防止代码中发生意外事件),以防 null 对象传入。在空值检查之前使用 //noinspection ConstantConditions 指令,以指示 IDE 禁止显示警告(因为您出于正当理由检查 null)。

随机的 NPE 表示库/api 作者可能遗漏了某些内容,并且存在未在其代码中处理的 bug。

非法参数异常(或带有问题描述的NPE - 在这种情况下使用的例外是基于意见的参数)表示调用方在调用方法的方式上犯了错误。

但最终,在你已经用@NonNull注释后是否测试空值将是基于意见和情况的。


推荐