注解

定义

注解不能有实体,编译器禁止为注解类指定类主体

  1. 使用 annotation class 定义一个注解类

  2. 语法类似于 主构造函数的声明

  3. 注解类的所有参数,必须被声明为 val。如下:

  4. 注解类的参数可以指定默认值。

    annotation class Test(val age: String,val score:Int = 40)
    
  5. 注解的调用与构造函数调用一样。 可以使用命名参数法以及省略掉带默认值的参数。如下例,使用全名参数法为 age 指定值,同时省略了有默认值的 score 参数:

    @Test(age = "aaa")
    fun test() = println("test")
    
  6. 注解的实参只能拥有以下数据类型:基本数据类型,字符串,枚举,类引用,其他的注解类,以及这些类的数组。

  7. 注解的 实参在编译时期必须已知。因此注解的实参必须是常量 —— 变量必须使用 const 修饰。


元注解

使用在注解上的注解被称为元注解

  1. 对注解使用 Target 注解,并将其值设置为 ANNOTATION_CLASS,即可将该注解声明为元注解

    @Target(AnnotationTarget.ANNOTATION_CLASS)
    annotation class Test(val age: String,val score:Int = 40)
    
  2. 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[],可以使用在注解作为参数类型。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容