使用 kotlin.Deprecated,优雅废弃你的过时代码

2,167 阅读4分钟

代码废弃

  随着项目的发展,许多老旧的代码面临了过时甚至需要废弃的情景,因此不知道如何系统地废弃代码成为了许多程序员在编程中的痛点,本文将讲解如何使用Kotlin强大的Deprecated注解来完成项目中的代码废弃流程。

Java和Koltin的@Deprecated

  很多Kotlin程序员以前都是写java过来的,而使用的最多的则是java自带的注解,如下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

  这个注解的作用就是会让IDE知道当前的方法废弃了,仅此而已。如果你希望得到更多的信息,你只能“期盼”作者在注释中给你留下更多的信息,否则你将面对一个过时的方法无所适从。

image.png

java的String中的某个被废弃的构造函数,其代替者则被写在方法注释中

  Java的废弃注解足够的“简陋纯粹”,以至于所有第一次见到这个注解的开发者都能迅速上手,给所有你需要废弃方法、属性、类加上注释即可。

  我们再看看kotlin的@Deprecated

@Target(CLASS, FUNCTION, PROPERTY, ANNOTATION_CLASS, CONSTRUCTOR, PROPERTY_SETTER, PROPERTY_GETTER, TYPEALIAS)
@MustBeDocumented
public annotation class Deprecated(
    val message: String,
    val replaceWith: ReplaceWith = ReplaceWith(""),
    val level: DeprecationLevel = DeprecationLevel.WARNING
)

  可以看出,kotlin的废弃注解不再是一个纯粹的注解,注解中还添加了三个成员属性,我们逐一讲解这些属性的作用:

message:提示用户为什么要废弃这个注解以及推荐用户使用哪些新方法来代替原方法。

replaceWith:将当前废弃的代码块替换成新的代码(重点)。

level:废弃等级,有警告错误隐藏三种。

正确使用kotlin.Deprecated

一、只使用message属性

我们使用以下代码作为演示,一个废弃方法,一个新方法,以及调用它们的方法:

image.png

image.png

给第一个方法添加了Deprecated注解之后,调用处出现了删除线标记,同时鼠标放上去之后可以看到message属性的内容。

到这里kotlin和java的废弃注解依然非常相似,但是我们重新看Deprecated,AS给我们一个大大的警告,说明我们目前的使用并不规范。

image.png

二、配合ReplaceWith属性使用

  上文提到AS告诉我们需要添加一个ReplaceWith对象,于是我们点击提示按钮,可以看到系统为我们自动生成了一个表达式。

image.png

这样有什么用呢,我们回到调用方法的地方,鼠标放上去发现提示变了,多了一个Replace with 'xxx'的按钮。点击按钮,会发现方法代码自动变成了ReplaceWith里面的代码。

image.png

image.png

点击系统提示的Replace with `newTestFun(carOne)`之后,系统为我们自动替换了函数调用。

结论:使用ReplaceWith可以让系统为我们自动替换代码,提高安全性

三、ReplaceWith属性的import

@Target()
@Retention(BINARY)
@MustBeDocumented
public annotation class ReplaceWith(val expression: String, vararg val imports: String)

ReplaceWith还有一个可变的字符串参数,这个是用于expression中包含了其他包的表达式的时候,知道如何正确导包用的,例如我们要在expression中使用安卓的Log,则需要导入Log的包,如下:

@Deprecated("当前方法废弃了,请使用newTestFun", ReplaceWith("Log.d(\"log\", varOne)", "android.util.Log"))
fun deprecatedTestFun(varOne:String,varTwo:Int){

}

四、觉得自己实现ReplaceWith非常麻烦不想写怎么办

如果你和笔者一样有这个烦恼的话,你可以像一开始那样,把注解中的ReplaceWith删掉,然后在需要废弃的方法体中,实现新版的方法,然后再利用系统的提示自动生成ReplaceWith即可。

image.png

点击Add提示之后,注解自动生成了ReplaceWith

image.png

五、合理使用Level

在Jetbrains看来,一个api的废弃需要遵循以下的生命周期(可以跳过某些步骤):

image.png

图片来自互联网

Warning是废弃注解默认的等级,即会在IDE中提示当前api过时了,并提供相应的解决方案,这对于那些调用了也不会有很大问题的api来说是一个不错的选项。

image.png

Error会让调用当前方法的地方产生报错提示,如果你的api已经严重过时,甚至会导致逻辑问题时,建议你使用这个。

image.png

Hidden则会让方法彻底无法被开发者看见,这是一个api即将被删除的倒数第二个阶段,完成测试之后就把api删除了吧。

image.png

总结

合理使用kotlin.Deprecated可以让我们安全高效地替换掉项目中那些老旧过时的代码。