定义
注解不能有实体,编译器禁止为注解类指定类主体
-
使用
annotation class
定义一个注解类 -
语法类似于 主构造函数的声明:
-
注解类的所有参数,必须被声明为
val
。如下: -
注解类的参数可以指定默认值。
annotation class Test(val age: String,val score:Int = 40)
-
注解的调用与构造函数调用一样。 可以使用命名参数法以及省略掉带默认值的参数。如下例,使用全名参数法为 age 指定值,同时省略了有默认值的 score 参数:
@Test(age = "aaa") fun test() = println("test")
-
注解的实参只能拥有以下数据类型:基本数据类型,字符串,枚举,类引用,其他的注解类,以及这些类的数组。
-
注解的 实参在编译时期必须已知。因此注解的实参必须是常量 —— 变量必须使用
const
修饰。
元注解
使用在注解上的注解被称为元注解
-
对注解使用
Target
注解,并将其值设置为ANNOTATION_CLASS
,即可将该注解声明为元注解@Target(AnnotationTarget.ANNOTATION_CLASS) annotation class Test(val age: String,val score:Int = 40)
-
AnnotationTarget.PROPERTY 表示应用到属性上,但 java 中无法使用声明为 PROPERTY 的注解,必须添加 FIELD 值才行。
@Target(AnnotationTarget.ANNOTATION_CLASS,AnnotationTarget.PROPERTY,AnnotationTarget.FIELD) annotation class Test(val age: String,val score:Int = 40)
使用类引用做实参
注解的实参可以是类引用
将一个参数的类型指定为 KClass,表示该参数需要的实参是一个类的 class 对象,kt 中通过 类名::class
可以获取指定类的 class 对象。
@Target(AnnotationTarget.FUNCTION)
annotation class Test(val age: KClass<out Any>, val score: Int = 40)
@Test(age = String::class)
fun test() = println()
KClass 的类型使用了协变,因为可以接收 String::class。如果不使用协变,则 age 的实参只能是 Any::class。
泛型类为参数
注解的形参可以使用泛型。
annotation class CustomSerializer(val serializerClass: KClass<out ValueSerializer<*>>)
注解类为实参
注解的实参可以是另外的注解。
如下,Test2 以 Test 为形参,因此在使用 Test2 时需要创建一个 Test 实例。此处与普通的调用构造函数类似。
annotation class Test(val name:String)
@Target(AnnotationTarget.CLASS)
annotation class Test2(val age:Int,val test:Test)
@Test2(age = 10,test = Test("name"))
class Person()
数组为实参
泛型的形参可以是数组类型。为数组类型传递实参时,需使用 arrayOf 函数。如下,test 注解需要两个 String 数组,
annotation class Test(val name: Array<String>, val age: Array<String>)
@Test(["2", "3"], arrayOf("3", "3"))
class Person()
参数写法
注解的实参可以是基本数据类型、字符串、枚举、类引用、注解类的数组。对于基本数据类型定义成数组时,使用使用IntArray 或其他相似的类;对于其余的需要使用 Array<String>(修改泛型实参)
annotation class Test(val name: Array<String>, val age: IntArray)
这是因为 IntArray 对应 java 中的 int[],是基本数据类型的数组;如果写成 Array<Int> 其对应的是 Integer[],不是基本数据类型。
对于 String 来说,StringArray 是一个单独的类,不是数组,所以不能用于此处 。而 Array<String> 是 String[],可以使用在注解作为参数类型。
网友评论