类比思维是非常实用的思维方式,我们跟Java的注解进行对比,就可以快速理解Kotlin的注解。
Java 代码:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.stereotype.Component;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface DomainAbilityProvider {
/**
* 领域
*
* @return 领域
*/
DomainEnum domain();
/**
* 能力提供方
*
* @return 能力提供方
*/
String provider();
}
Kotlin代码:
对应到 Kotlin 的注解里就是:
package com.lightsword.da
import org.springframework.stereotype.Component
/**
* @author: Jack
* 2021/3/16 上午11:18
*
* 1.Kotlin中的元注解类定义于kotlin.annotation包中,主要有: @Target、@Retention、@Repeatable、@MustBeDocumented 4种元注解
* 2.相比Java中5种元注解: @Target、@Retention、@Repeatable、@Documented、@Inherited少了 @Inherited元注解。
* 3.注解类中只能拥有如下类型的参数: 基本数据类型、字符串、枚举、类引用类型、其他的注解类(例如Deprecated注解类中的ReplaceWith注解类)
*/
@Target(AnnotationTarget.TYPE)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
@Component
annotation class DomainAbilityProvider(
/**
* 领域
*/
val domain:DomainEnum,
/**
* 能力提供方
*/
val provider:String
)
元编程:关于编程中的注解
一、注解的本质
注解实际上就是一种代码标签,它作用的对象是代码。它可以给特定的注解代码标注一些额外的信息。然而这些信息可以选择不同保留时期,比如源码期、编译期、运行期。然后在不同时期,可以通过某种方式获取标签的信息来处理实际的代码逻辑,这种方式常常就是我们所说的反射。
二、注解的定义
在Kotlin中注解核心概念和Java一样,注解就是为了给代码提供元数据。并且注解是不直接影响代码的执行。一个注解允许你把额外的元数据关联到一个声明上,然后元数据就可以被某种方式(比如运行时反射方式以及一些源代码工具)访问。
三、注解的声明(标签的声明)
在Kotlin中的声明注解的方式和Java稍微不一样,在Java中主要是通过@interface关键字来声明,而在Kotlin中只需要通过annotation class来声明, 需要注意的是在Kotlin中编译器禁止为注解类指定类主体,因为在Kotlin中注解只是用来定义关联的声明和表达式的元数据的结构。
1、Kotlin注解声明
package com.mikyou.annotation
//和一般的声明很类似,只是在class前面加上了annotation修饰符
annotation class TestAnnotation(val value:String)
2、Java注解声明
package com.mikyou.annotation;
//java中的注解通过@interface关键字进行定义,它和接口声明类似
public @interface TestAnnotation{
String value();
}
Kotlin中的元注解
和Java一样在Kotlin中,一个Kotlin注解类自己本身也可以被注解,可以给注解类加注解。我们把这种注解称为元注解,可以把它理解为一种基本的注解,可以把它理解为一种特殊的标签,用于标注标签的标签。
Kotlin中的元注解类定义于kotlin.annotation包中,主要有: @Target、@Retention、@Repeatable、@MustBeDocumented 4种元注解相比Java中5种元注解: @Target、@Retention、@Repeatable、@Documented、@Inherited少了 @Inherited元注解。
@Target元注解
1、介绍
Target顾名思义就是目标对象,也就是这个标签作用于哪些代码中目标对象,可以同时指定多个作用的目标对象。
2、源码定义
@Target(AnnotationTarget.ANNOTATION_CLASS)//可以给标签自己贴标签
@MustBeDocumented
//注解类构造器参数是个vararg不定参数修饰符,所以可以同时指定多个作用的目标对象
public annotation class Target(vararg val allowedTargets: AnnotationTarget)
3、@Target元注解作用的目标对象
在@Target注解中可以同时指定一个或多个目标对象,那么到底有哪些目标对象呢?这就引出另外一个AnnotationTarget枚举类
public enum class AnnotationTarget {
CLASS, //表示作用对象有类、接口、object对象表达式、注解类
ANNOTATION_CLASS,//表示作用对象只有注解类
TYPE_PARAMETER,//表示作用对象是泛型类型参数(暂时还不支持)
PROPERTY,//表示作用对象是属性
FIELD,//表示作用对象是字段,包括属性的幕后字段
LOCAL_VARIABLE,//表示作用对象是局部变量
VALUE_PARAMETER,//表示作用对象是函数或构造函数的参数
CONSTRUCTOR,//表示作用对象是构造函数,主构造函数或次构造函数
FUNCTION,//表示作用对象是函数,不包括构造函数
PROPERTY_GETTER,//表示作用对象是属性的getter函数
PROPERTY_SETTER,//表示作用对象是属性的setter函数
TYPE,//表示作用对象是一个类型,比如类、接口、枚举
EXPRESSION,//表示作用对象是一个表达式
FILE,//表示作用对象是一个File
@SinceKotlin("1.1")
TYPEALIAS//表示作用对象是一个类型别名
}
@Retention元注解
1、介绍
Retention对应的英文意思是保留期,当它应用于一个注解上表示该注解保留存活时间,不管是Java还是Kotlin一般都有三种时期: 源代码时期(SOURCE)、编译时期(BINARY)、运行时期(RUNTIME)。
2、源码定义
@Target(AnnotationTarget.ANNOTATION_CLASS)//目标对象是注解类
public annotation class Retention(val value: AnnotationRetention = AnnotationRetention.RUNTIME)//接收一个参数,该参数有个默认值,默认是保留在运行时期
3、@Retention元注解的取值
@Retention元注解取值主要来源于AnnotationRetention枚举类
public enum class AnnotationRetention {
SOURCE,//源代码时期(SOURCE): 注解不会存储在输出class字节码中
BINARY,//编译时期(BINARY): 注解会存储出class字节码中,但是对反射不可见
RUNTIME//运行时期(RUNTIME): 注解会存储出class字节码中,也会对反射可见, 默认是RUNTIME
}
@MustBeDocumented元注解
1、介绍
该注解比较简单主要是为了标注一个注解类作为公共API的一部分,并且可以保证该注解在生成的API文档中存在。
2、源码定义
@Target(AnnotationTarget.ANNOTATION_CLASS)//目标对象只能是注解类
public annotation class MustBeDocumented
@Repeatable元注解
1、介绍
这个注解决定标注的注解在一个注解在一个代码元素上可以应用两次或两次以上。
2、源码定义
@Target(AnnotationTarget.ANNOTATION_CLASS)//目标对象只能是注解类
public annotation class Repeatable
参考资源:
https://www.jianshu.com/p/8392c63b0f52