Java注解与Kotlin的兼容性


Java注解与Kotlin完全兼容,只是在使用时略加注意即可。

一、指定注解的作用目标

为注解指定作用目标的语法格式:

@目标:注解(注解属性值)

如果在同一个目标上要指定多个注解,则需要将多个注解放在方括号中,并用空格隔开,语法格式如下:

@目标:[注解1(注解属性值) 注解2(注解属性值), ....]

Kotlin支持的目标包含如下几个:

  • file:指定注解对文件本身起作用。
  • property:指定注解对整个属性起作用。(这种目标的注解对Java不可见,因为Java没有真正的属性)
  • field:指定注解对属性的幕后字段起作用。
  • get:指定注解对属性的getter方法起作用。
  • set:指定注解对属性的setter方法起作用。
  • receiver:指定注解对扩展方法或扩展属性的接收者起作用。
  • param:指定注解对构造器的参数起作用。
  • setparam:指定注解对setter方法的参数起作用。
  • delegate:指定注解对委托属性存储其委托实例的字段起作用。
package test0710

//先定义两个注解
annotation class MyTag

annotation class FkTag(val info: String)

class Item {
    //指定注解只对getter方法起作用
    @get:[MyTag FkTag(info = "补充信息")]
    var name: String = "Kotlin"
}

fun main(args: Array<String>) {
    //获取Item类对应的Java类
    val clazz = Item::class.java
    //遍历clazz类所包含的全部方法
    for (mtd in clazz.declaredMethods) {
        println("--方法${mtd}上的注解如下---")
        //遍历该方法上直接声明的所有注解
        for (an in mtd.declaredAnnotations) {
            println(an)
        }
    }

    //遍历clazz类所包含的全部成员变量
    for (f in clazz.declaredFields) {
        println("--方法${f}上的注解如下--")
        //遍历该成员变量上直接声明的所有注解
        for (an in f.declaredAnnotations) {
            println(an)
        }
    }
}

输出结果:

--方法public final java.lang.String test0710.Item.getName()上的注解如下---
@test0710.MyTag()
@test0710.FkTag(info="补充信息")
--方法public final void test0710.Item.setName(java.lang.String)上的注解如下---
--方法private java.lang.String test0710.Item.name上的注解如下--

如果要指定注解作用于整个文件本身,则必须将注解放在package语句之前,或者所有导包语句之前。

//指定@FileTag注解作用于整个文件
@file:FileTag("fileTag")
package com.hxl.test

如果要指定注解作用于扩展方法或扩展属性的接收者,则使用带receiver:的注解修饰整个扩展方法或扩展属性即可。

//指定@MyTag注解作用于扩展方法的接收者
fun @receiver:MyTag String.fun(){ }

二、使用Java注解

Kotlin完全兼容Java注解,可以直接在Kotlin程序中使用Java注解。

Java注解的成员变量是没有顺序的,只能通过属性名来设置属性值,Kotlin注解的属性还可以通过位置来设置属性值。

public @interface JavaTag {
    public String name();

    public int age();
}
annotation class KotlinTag(val name: String, val age: Int)
//Kotlin注解可通过位置来指定属性值
@KotlinTag("Kotlin", 4)
class Book {
    //Kotlin注解也可以通过属性名来指定属性值
    @KotlinTag(name = "kotlin", age = 5)
    //Java注解只能通过属性名来指定属性值
    @JavaTag(name = "Java", age = 80)
    fun test() {

    }
}

如果Java注解中的value属性是数组类型,它会变成Kotlin注解的vararg属性,直接为它传入多个属性值即可。

public @interface JavaTagWithArray {
    public String[] value();
}
//直接传入多个属性值
@JavaTagWithArray("Java", "Kotlin", "Go")
class Stock

如果其他名称的属性是数组类型,在Kotlin中使用该注解时必须显式使用arrayOf()函数来构建数组。

public @interface JavaTagWithArray {
    public String[] infos();
}
//对于名称不是value的属性,需要显式使用arrayOf()函数来构建数组
@JavaTagWithArray(infos=arrayOf("Java", "Kotlin", "Go"))
class Stock

学海无涯苦作舟

我的微信公众号.jpg


文章作者: HunterArley
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 HunterArley !
评论
  目录