We all know that Java has an java.lang.Deprecated
annotation to mark an API as "deprecated", or "not recommended". Such as String
classes, there is a marked Deprecated
constructor:
@Deprecated
public String(byte ascii[], int hibyte) {
this(ascii, hibyte, 0, ascii.length);
}
Java also provides a @deprecated
document label, used to provide relevant information.
This annotation has several flaws:
- It is impossible to prohibit the use of obsolete APIs, and a single compilation warning cannot prevent the stroke programmer
- Cannot provide enough information, why is this API obsolete? Which API should be used instead? After all, documentation comments are not mandatory.
For this problem, Kotlin solution is to kotlin.Deprecated
comment, it is more than java.lang.Deprecated
more powerful and user-friendly.
kotlin.Deprecated
The statement is as follows:
@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
)
@Target
RepresentsDeprecated
can be used in classes, functions, attributes, annotation class constructor, getter, setter and type alias;@MustBeDocument
Indicates that itDeprecated
is a public API and must be included in the API documentation.
We focus on three parameters:
The first parameter is very simple, String type message, need to explain the reason for discarding here.
@Deprecated("this function is deprecated!")
fun oldAdd(a: Int, b: Int) {
println(a + b)
}
fun main(args: Array<String>) {
oldAdd(1, 2)
}
For example, we define the function oldAdd above, and mark it with Deprecated. If this function is called, a compilation warning will appear:
Warning:(7, 5) Kotlin: ‘oldAdd(Int, Int): Unit’ is deprecated. this function is deprecated!
The this function is deprecated! we gave when defining Deprecated appeared in the warning message, which makes it a lot easier for us to troubleshoot.
The third parameter is DeprecationLevel
one of the three obsolete levels defined in this enumeration. Deprecated
Different levels of warning are given where the API is used :
public enum class DeprecationLevel {
WARNING,
ERROR,
HIDDEN
}
- WARNING: The default option, the compilation will still succeed, but a compilation warning will appear;
- ERROR: Compile error, which is equivalent to prohibiting the use of this API;
- HIDDEN: Hidden, this API cannot be called.
Let's change the above code and add a custom obsolete level:
@Deprecated(
"this function is deprecated!",
ReplaceWith(""), // 无法省略
level = DeprecationLevel.ERROR
)
fun oldAdd(a: Int, b: Int) {
println(a + b)
}
Compiling again will cause a compilation error, and the compilation fails directly:
Error:(11, 5) Kotlin: Using ‘oldAdd(Int, Int): Unit’ is an error. this function is deprecated!
If replaced by HIDDEN
:
Error:(11, 5) Kotlin: Unresolved reference: oldAdd
Can't find this function...
The last is the second parameter, which needs to be the ReplaceWith type, which is an annotation type (because the annotation parameters can only be basic types, String, and annotation types). The statement is as follows:
@Target()
@Retention(BINARY)
@MustBeDocumented
public annotation class ReplaceWith(val expression: String, vararg val imports: String)
expression
Is the code segment to be replaced, intelligent replacement parameters;imports
It is a dependency that requires additional import.
Define a function newAdd
and put it in the new
package:
package new
fun newAdd(a: Int, b:Int) {
println("$a + $b = ${a + b}")
}
Then modify the oldAdd
function:
@Deprecated(
"this function is deprecated!",
ReplaceWith("newAdd(a, b)", "new.newAdd")
)
fun oldAdd(a: Int, b: Int) {
println(a + b)
}
Thus, we can press the IDEA in Alt + Enter
a key replacement:
automatically matching parameter when replacing, and import-dependent defined Imports:
Original link: https://zhuanlan.zhihu.com/p/32890550