当前位置: 首页 > news >正文

NullAway:Android上的NullPointerExceptions的开源工具

NullPointerExceptions (NPE)。空指针异常

NullAway:https://github.com/uber/NullAway

介绍 NullAway

NullAway 的核心是基于开源类型的 NPE 检查器,用于 Java 代码。要使用 NullAway,你必须先在代码(字段,方法参数或返回值为 null)中添加 @Nullable 注释。(由于我们以前使用 Eradicate ,我们已经在我们的代码库中有这些注释。)给定这些注释,NullAway 执行本地的一系列一致性检查,以确保在代码中取消引用的任何指针不能为空。

NullAway 是一个用于查找框架 Error Prone bug 的检查插件。Error Prone 的运行代码检查作为 Java 编译过程标准的一部分。此编译器的集成允许检查编译器已经完成的工作,如代码解析和类型检查。此外,NullAway 和 Error Prone 可直接集成到我们用于 Android 代码的构建工具 Buck 所支持的快速内存并行构建中。因此,NullAway 可以比在正常构建过程之外运行的工具快得多。

我们发现,NullAway 在正常构建时间中只用了很少的开销(约占 10%)。因此,我们配置了 NullAway,不仅仅是在提交队列中运行,而是运行在我们的 Android 代码的每一个版本上。

将 NullAway 整合到我们所有的 Java 构建中的价值表现在以下三个方面:

  • 立即反馈:集成到所有版本中,使开发人员能够在引入潜在的 NPE 时立即获得反馈,而不必等待提交队列。

  • 没有 NPE 检查器:构建集成意味着我们不再需要在提交队列上作为单独的作业运行无效检查器,从而节省了大量的机器资源。

  • 降低提交队列延迟:NullAway 能够显着降低提交队列延迟,因为由于 NPE 警告而导致提交队列失败变得非常罕见 ; 这个减少的延迟在我们转向monorepo之后变得更加显着。

使用 NullAway

img_2723ce96d53bbb5e23aa80976802a5ff.jpe
image

图 2:在三个简单的步骤中,NullAway 确定方法m中的表达式e是否为空.

要了解 NullAway 的工作原理,让我们考虑一下如何确定程序中的一些表达式是否为空,这是空值检查所需要的。请考虑以下示例:

class A {
 @Nullable Object f;
}
static void m(A x) {
 if (x.f != null) {
   System.out.println(x.f.toString());
 }
}

在上面的示例中,NullAway 尝试显示x不为空,以确保 x.f 不会导致 NPE,并且 x.f 在调用 xftoString() 时也不为null

对于不应该为null的表达式,NullAway 首先尝试快速证明表达式 是非空的,例如,通过检查其类型是否不是 @Nullable ,或者是否是不能为nullnew Object() 的表达式。

例如,由于x的声明没有注释为 @Nullable ,所以 NullAway 可以假设它不为空,从而显示 x.f 是安全的。NullAway 通过确定 @Nullable 表达式从不作为参数传递给方法m的方式执行这一假设。

如果快速检查失败,NullAway 试图使用数据流分析和充分利用检查框架现有的库显示非 null 的含量。数据流分析的一个主要目的是发现代码中的现有 null。

对于上面的例子中的 xftoString() 调用,快速检查不能显示 x.f 不能为 null,因为 A.f 字段是 @Nullable 。然而,我们的数据流分析使用封闭的条件检查, xf!= null 来表示 x.f.toString() 的调用是安全的。由于数据流分析可能很昂贵(它需要计算控制流图并运行定点计算),所以 NullAway 每个方法只运行一次分析,并缓存结果。

在 NullAway GitHub 页面上,有关于如何在 Android 应用程序或其他 Uber Engineering 和开源的 NullAway 上运行该工具的详细说明,NullAway 是消除 NPE 的快速实用工具,帮助其他人部署更可靠的 Android 应用程序。有关 NullAway 的详细检查,错误信息和限制的更多详细信息,请参阅我们的实施指南。

链接:

https://github.com/uber/NullAway/wiki

原文链接:

https://eng.uber.com/nullaway/

相关文章:

  • ASP.NET MVC Model元数据(五)
  • Android 解决ListView 和 ScrollView 共存冲突的问题
  • [Web开发] Web 2.0 网站估价工具
  • c#中的反射机制
  • 利用QRmaker制作二维码
  • CentOS 6.8 部署django项目二
  • GHOST
  • 磁盘与文件系统管理之五
  • SQL Server 2008 存储结构之DCM、BCM
  • 网络管理员的基本素质
  • 一步一步学会puppet(二)--模块和类
  • DHCP用户类选项配置
  • [Unity3d]安卓无法加载assetbundle的问题
  • jquery.idTabs使用方法
  • Windows Workflow Foundation学习资源
  • @angular/forms 源码解析之双向绑定
  • __proto__ 和 prototype的关系
  • 【RocksDB】TransactionDB源码分析
  • co模块的前端实现
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • EOS是什么
  • Java IO学习笔记一
  • JAVA多线程机制解析-volatilesynchronized
  • js写一个简单的选项卡
  • Mithril.js 入门介绍
  • NLPIR语义挖掘平台推动行业大数据应用服务
  • PHP CLI应用的调试原理
  • python 装饰器(一)
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • vue自定义指令实现v-tap插件
  • 百度地图API标注+时间轴组件
  • 不上全站https的网站你们就等着被恶心死吧
  • 翻译:Hystrix - How To Use
  • 猴子数据域名防封接口降低小说被封的风险
  • 基于游标的分页接口实现
  • 两列自适应布局方案整理
  • 人脸识别最新开发经验demo
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • No resource identifier found for attribute,RxJava之zip操作符
  • linux 淘宝开源监控工具tsar
  • raise 与 raise ... from 的区别
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​学习一下,什么是预包装食品?​
  • #define,static,const,三种常量的区别
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (a /b)*c的值
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (六)vue-router+UI组件库
  • (七)Java对象在Hibernate持久化层的状态
  • (七)Knockout 创建自定义绑定
  • (一)kafka实战——kafka源码编译启动
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • ******之网络***——物理***
  • **PHP二维数组遍历时同时赋值
  • .NET MVC 验证码