Error Prone是一款开源的、用于帮助开发者在编译期间查找代码缺陷的代码检查工具,适用于Java及Android开发,该工具:
工作示例:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new RuntimeException(); }
错误: [DeadException] Exception created but not thrown new RuntimeException(); ^ (see http://errorprone.info/bugpattern/DeadException) Did you mean 'throw new RuntimeException();'? 1 个错误
ErrorProne在Maven、Ant等的相关配置可参看(链接 http://errorprone.info/docs/installation),这里只关心如何在Android Studio中配置ErrorProne插件,如下:
buildscript { repositories { maven { url "https://plugins.gradle.org/m2/" } } dependencies { classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.10" } } apply plugin: "net.ltgt.errorprone"
需要注意的是,gradle error-prone插件各版本对可支持的gradle和javac版本有不同要求,具体的参照 https://github.com/tbroyer/gradle-errorprone-plugin
Error Prone的各项check是基于Bug Patterns,每项Check都有对应的严重级别设置,Error Prone允许用户通过修改严重级别来打开或关闭指定check,通用的设置模板如下:
-Xep:<checkName>[:severity]
其中,checkName是待修改check项的名字,severity是该check对应设置为的严重级别,取{“OFF”, “WARN”, “ERROR”}之一。例如:
-Xep:ReferenceEquality [turns on ReferenceEquality check with the severity level from its BugPattern annotation] -Xep:ReferenceEquality:OFF [turns off ReferenceEquality check] -Xep:ReferenceEquality:WARN [turns on ReferenceEquality check as a warning] -Xep:ReferenceEquality:ERROR [turns on ReferenceEquality check as an error] -Xep:ReferenceEquality:OFF -Xep:ReferenceEquality [turns on ReferenceEquality check]
同时,Error Prone也支持统一的处理,如下:
-XepAllErrorsAsWarnings
所有check的ERROR改为WARN级别-XepAllDisabledChecksAsWarnings
打开所有关闭的check并设为WARN级别-XepDisableAllChecks
关闭所有check-XepDisableWarningsInGeneratedCode
关闭所有针对生成的代码的WARN-XepIgnoreUnknownCheckNames
忽略check名不可识别时的报错 具体配置实例如下:
tasks.withType(JavaCompile) { options.compilerArgs += [ '-Xep:DeadException:WARN', '-Xep:GuardedByValidator:OFF' ] }
需要注意的是,在AndroidStudio中,如果检查出ERROR级别的bug,在提示的同时本次构建会失败,所以如果不是在用于持续构建情景而是日常开发中,最好关闭或更改设置那些默认ERROR级别的检查项。
目前,error prone默认执行的ERROR级别的check共97项,包括ArrayToString等。
默认执行的WARN级别的check共59项,涉及DefaultCharset等。
除此之外,还提供了一些实验性的check,这些check默认是关闭的,例如EmptyIf等。
配置check时,可以通过自定义标签来将额外信息传递给BugChecks,配置模板如下:
-XepOpt:[Namespace:]FlagName[=Value]
通常为了避免自定义标签命名冲突,如果标签只用于一个检查或一组检查,可以考虑在标签名前增加命名空间。另外如果标签未赋值,默认为赋值true,即-XepOpt:MakeAwesome
等同于-XepOpt:MakeAwesome=true
使用示例:
-XepOpt:FlagName=SomeValue (flags["FlagName"] = "SomeValue") -XepOpt:BooleanFlag (flags["BooleanFlag"] = "true") -XepOpt:ListFlag=1,2,3 (flags["ListFlag"] = "1,2,3") -XepOpt:Namespace:SomeFlag=AValue (flags["Namespace:SomeFlag"] = "AValue")
在BugChecker中通过增加一个入参类型为ErrorProneFlags的构造函数来访问这些标签,如下:
public class MyChecker extends BugChecker implements SomeTreeMatcher { private final boolean coolness; public MyChecker(ErrorProneFlags flags) { // The ErrorProneFlags get* methods return an Optional
Error Prone是允许建立新检查项的,在创建前需要尽量遵守以下的基本原则:
Error Prone提供了97个Error级别的默认检查项,均对应着java中的某些经典错误用法。
例如:
ArrayEquals Reference equality used to compare arrays 问题说明: java中Object#equals比较的是两个对象实例的堆内存首地址,地址不同返回false,即两个变量指向的不是同一对象,则两者不同;但是String类和Array类重写了Object中的equals方法,比较的是內容;非String和Array类型的变量,“==”和“equals”作用相同,比较的是堆内存首地址。 因此,如果是比较两个数组引用的一致性,应该使用==代替Object.equals,如果是比较两个数组的内容一致性,使用Array#equals(). 问题警告忽略: 在闭合元素前增加@SuppressWarnings("ArrayEquals")注解
其实到这里,如何在工作中部署Error Prone已经解决了,但俗话说,前车之鉴,后事之师,研究这些经典的Error检查的同时,对于提升Java编码能力一定是有帮助的。后续我会对97个检查项进行研究,并在后续拿出来与大家交流~
http://errorprone.info/index
https://plugins.gradle.org/plugin/net.ltgt.errorprone
https://github.com/tbroyer/gradle-errorprone-plugin
http://blog.csdn.net/littlesmallless/article/details/69939258
https://github.com/google/error-prone/blob/master/check_api/src/main/java/com/google/errorprone/ErrorProneOptions.java
ErrorProneTest