快速上手
Kotlin
@Target(
AnnotationTarget.CLASS,
AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.EXPRESSION,
AnnotationTarget.CONSTRUCTOR
)
@Retention(AnnotationRetention.SOURCE)
@Repeatable
@MustBeDocumented
annotation class MyAnnotation
@MyAnnotation @MyAnnotaion class Test @MyAnnotation constructor(val name: String) {
@MyAnnotation fun test(@MyAnnotation num: Int): Int = (@MyAnnotation 1)
}
注解的声明
注解使用关键字annotation
来声明,比如快速上手中的例子,使用annotation class MyAnnotation
就声明了一个注解,我们可以按照定义的规则将其放在其他元素身上
元注解
下面的注解了解过Java的肯定不陌生,元注解就是可以放在注解上面的注解
-
@Target
: 用来指定注解可以应用到哪些元素上,有以下可选项- CLASS: 可以应用于类、接口、枚举类
- ANNOTATION_CLASS: 可以应用于注解
- TYPE_PARAMETER
- PROPERTY
- FIELD
- LOCAL_VARIABLE
- VALUE_PARAMETER: 可以应用于字面值
- CONSTRUCTOR: 可以应用于构造函数
- FUNCTION: 可以应用于函数
- PROPERTY_GETTER
- PROPERTY_SETTER
- TYPE
- EXPRESSION: 可以应用于表达式
- FILE
- TYPEALIAS
-
@Retention
: 用来指定注解的生命周期- SOURCE: 仅保存在源代码中
- BINARY: 保存在字节码文件中,但是运行是无法获取
- RUNTIME: 保存在字节码文件中,运行时可以获取
-
@Repeatable
: 允许此注解可以在单个元素上多次使用
拿上方的代码来简单介绍几个元注解
@Target
可以看一下@Target
的源码
Kotlin
* This meta-annotation indicates the kinds of code elements which are possible targets of an annotation.
*
* If the target meta-annotation is not present on an annotation declaration, the annotation is applicable to the following elements:
* [CLASS], [PROPERTY], [FIELD], [LOCAL_VARIABLE], [VALUE_PARAMETER], [CONSTRUCTOR], [FUNCTION], [PROPERTY_GETTER], [PROPERTY_SETTER].
*
* @property allowedTargets list of allowed annotation targets
*/
@Target(AnnotationTarget.ANNOTATION_CLASS)
@MustBeDocumented
public annotation class Target(vararg val allowedTargets: AnnotationTarget)
在源码中可以看到,Target注解中要传入的参数为allowedTargets
,使用了vararh
关键字,可传入多个参数,参数的类型为AnnotationTarget
,它是一个枚举类,再进入AnnotationTarget
的源码就可以看到它有上方元注解中列出的那些。
在快速上手的示例中我们的@Target
中传入了Class FUNCTION VALUE_PARAMETER EXPRESSION CONSTRCTOR
,表示此注解可以放在类、接口、枚举、函数、字面值、表达式和构造函数上
@Retention
此注解就是指定它什么时候失效 默认是RUNTIME
, 快速上手中是用的SOURCE
,表示它仅存在于**「源码」中,在编译成字节码后将会消失,如果指定了BINARY
,则可以存在于字节码文件中,但是「运行时无法获取」**,反射无法获取
注解的属性
注解可在主构造参数内传值
Kotlin
annotation class MyAnnotation2(val effect: String)
class Test2 {
@MyAnnotation2("Test")
fun test() {
println("Run test")
}
}
比如上面的例子,可以在主构造函数内传入一个参数,参数支持的类型有以下几种
- Kotlin中的八种"「基本数据类型」"(Byte, Short, Int, Long, Float, Double, Boolean, Char)
- **「String」**类型
- **「引用」**类型(Class)
- **「枚举」**类型
- **「注解」**类型
- 以上类型的**「数组类型」** 需要注意的是,官网中特别说明参数不可以传入可空类型,比如"String?",因为JVM不支持null存储在注解的属性中
注解的作用
如果是熟悉Java的开发者对注解的作用肯定是非常熟悉。 注解可以提供给**「编译器、运行时环境、其他代码库以及框架」提供很多可用信息。 可用作 「标记」,可供第三方技术库、框架识别信息,比如大家熟悉的SpringBoot,很多事情就是通过注解和反射来实现 可用来提供更多的 「上下文信息」**,比如方法的类型参数、返回值类型、错误处理等
后面可结合反射来深入理解Kotlin在开发中的用途