注解

作者: 一江碎月 | 来源:发表于2018-07-12 14:31 被阅读0次

    定义

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

    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[],可以使用在注解作为参数类型。

    相关文章

      网友评论

          本文标题:注解

          本文链接:https://www.haomeiwen.com/subject/umxrpftx.html