//Code to be added
kotlinOptions {allWarningsAsErrors=true}
那么问题可能就会被提出来,开启这一选项有什么好处呢,毕竟我需要修改很多文件。
通常情况下,开启后的作用,我们可以归纳为如下
发现更多的潜在问题和崩溃
减少不必要的代码(变量,参数)
发现不好的编码实践
发现更多的API弃用问题
最终增加代码的健壮性和优雅程度
如下,我们会通过一些实践来说明一些问题
Nothing to Inline(作用不大的内联)
123456789
@Suppress("NOTHING_TO_INLINE")inlinefunString?.isNotNullNorEmpty():Boolean{//Expected performance impact of inlining // 'public inline fun String?.isNotNullNorEmpty(): Boolean // defined in com.example.warningsaserrorscases in file NothingToInlineWarnings.kt'// is insignificant. // Inlining works best for functions with parameters of functional typesreturnthis!=null&&this.isNotEmpty()}
funtestInaccessibleType(){//Type RequestManager.TimelineRequest! is inaccessible in this context// due to: private open class TimelineRequest defined// in com.example.warningsaserrorscases.RequestManager@Suppress("INACCESSIBLE_TYPE")RequestManager.sInstance.timelineRequest}
上述的testInaccessibleType无法访问TimelineRequest的属性和方法
具体的解决办法,可以是设置TimelineRequest为public,而非private
必要时可以使用@Suppress("INACCESSIBLE_TYPE")压制警告
UNCHECKED_CAST(未检查的类型转换)
12345
fun<T>Any.toType():T?{//Unchecked cast: Any to T@Suppress("UNCHECKED_CAST")returnthisas?T}
funtestEnum1(){//Enum argument can be null in Java, but exhaustive when contains no null branchwhen(SeasonUtil.getCurrentSeason()){Season.SPRING->println("Spring")Season.SUMMER->println("Summer")Season.FALL->println("Fall")Season.WINTER->println("Winter")//else -> println("unknown")}}funtestEnum2(){//Enum argument can be null in Java, but exhaustive when contains no null branch@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")when(SeasonUtil.getCurrentSeason()){Season.SPRING->println("Spring")Season.SUMMER->println("Summer")Season.FALL->println("Fall")Season.WINTER->println("Winter")}}
interfaceOnViewClickedListener{funonViewClicked(viewId:Int)}funtestParameterNameChangedOnOverride(){// The corresponding parameter in the supertype 'OnViewClickedListener'// is named 'viewId'.// This may cause problems when calling this function with named arguments.object:OnViewClickedListener{overridefunonViewClicked(@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")id:Int){println("onViewClicked id=$id")}}}
funtestSenselessComparison(message:String){//Condition 'message != null' is always 'true'@Suppress("SENSELESS_COMPARISON")if(message!=null){}}
和前面的例子一样,这种检查是多余的,因为Kotlin内部会有Intrinsics做参数非空的与判断
建议主动移除无意义的比较
不建议压制警告
UNNECESSARY_NOT_NULL_ASSERTION(不需要的非空断言)
123456
funtestUncessaryNotNullAssertion(message:String){//Unnecessary non-null assertion (!!) on a non-null receiver// of type String@Suppress("UNNECESSARY_NOT_NULL_ASSERTION")println(message!!.toIntOrNull())}
这种断言是多余的,因为Kotlin内部会有Intrinsics做参数非空的与判断
建议主动移除不需要的非空断言
不建议压制警告
USELESS_IS_CHECK(没有用的实例类型检查)
1234567
funtestUselessIsCheck(message:String){//Check for instance is always 'true'@Suppress("USELESS_IS_CHECK")if(messageisString){}}
没有意义的类型检查,因为Kotlin内部会有Intrinsics做参数非空的与判断
建议主动移除不必要的检查
不建议压制警告
VARIABLE_WITH_REDUNDANT_INITIALIZER(变量初始化多余)
123456
funtestVariableWithRedundantInitializer(){//Variable 'message' initializer is redundant@Suppress("VARIABLE_WITH_REDUNDANT_INITIALIZER")varmessage:String?=null;message=System.currentTimeMillis().toString()println(message)}
funtestUnusedValue(){// The value '"Hello"' assigned to 'var message: String?// defined in com.example.warningsaserrorscases.test' is never used@Suppress("ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")varmessage:String?=null@Suppress("UNUSED_VALUE")message="Hello"}