注解本质上是一种代码的标签,做用的对象是代码。使用注解能够将额外的元数据关联到声明上,这些元数据能够被源代码工具和反射访问并作必定的操做。java
kotlin中的元素生成java中的元素可能有多个,好比kotlin中的属性会生成属性、getter和setter,因此生成的java文件中注释会有多个可能位置。在某些状况下,须要精准的指定应该生成该注解(类如@get:JvmStatic
),kotlin中支持的使用处目标有:markdown
file
:文件。property
:此注解对java不可见。field
:字段。get
:属性getter。set
:属性setter。receiver
:扩张函数或者属性的接受者参数,即赋值目标。param
:构造函数参数。setparm
:属性setter参数。delegate
:为委托属性存储其委托实例的字段。若是不指定使用处目标,会根据@Target
标注的能够做为目标的种类中选择目标。若是有多个适用目标,则根据param-property-field
的顺序选择第一个适用的目标。多线程
元注解就像它的名字同样,是注解中的基石。kotlin中定义了四个元注解,这四个注解是最基本的注解,他们都是用于给注解(包括他们自身)打标签,也就是注解的注解。函数
Target
:标注能够做为注释目标的元素种类,也就是标注的注释能够做用于类或者变量等等种的哪些种类。传入值是一个变长参数:枚举类AnnotationTarget
。AnnotationTarget
中定义了各类元素种类:工具
CLASS
:类、接口、注解类等。spa
ANNOTATION_CLASS
:仅注解类。线程
TYPE_PARAMETER
:泛型(不支持)。code
PROPERTY
:属性。orm
FIELD
:字段(字段和属性的区别是字段能够直接访问,属性须要经过getter和setter访问。但在kotlin中并不能手动声明字段,使用的效果和PROPPERTY
并无差异)。对象
LOCAL_VARIABLE
:局部变量。
VALUE_PARAMETER
:函数或者构造函数的入参。
CONSTRUCTOR
:构造函数。
FUNCTION
:不包含构造函数的函数。
PROPERTY_GETTER
:属性的getter方法。
PROPERTY_SETTER
:属性的setter方法。
TYPE
:类型(好比是Int,Double这些,在声明的时候能够给他们加上注解)。
EXPRESSION
:表达式。
FILE
:文件(须要配合@file明确注解目标,类如@file:JvmName("1")
)。
TYPEALIAS
:类型别名。
Retention
:标记注释的保留期,传入一个枚举类AnnotationRetention
。AnnotationRetention
中定义了三个时期:
SOURCE
:源代码时期,编译器会丢弃该注解。
BINARY
:编译时期,记录在CLASS文件中,运行时不会被JVM保留。
RUNTIME
:运行时期,会被JVM保留,能够进行反射读取他们,也是默认的保留期。
MustBeDocumented
:标注一个注释为公共API的一部分,保证该注解在生成的API文档中可见。
Repeatable
:标记一个注释能够在一个代码元素上屡次使用。
kotlin的语法和java的语法仍是有很大的不一样,针对这个问题,kotlin中预置了一些注解,解决与Java兼容问题。
JvmDefault
: kotlin中,给接口中的方法设置实体,反编译成java代码后,会在接口中生成一个静态内部类 DefaultImpls
,将方法的实体放入其中,对应的调用时都须要先调用这个静态内部类。使用JvmDefault
能够去除这个静态内部类,将方法实体直接放入了接口之中(JAVA8)。
JvmFiled
:kotlin中定义的公开属性,反编译成java中的属性是私有的且将setter和getter暴漏出来的,不能直接访问;加上JvmFiled
,变量在java中就成了公开变量,能够直接访问。在伴生对象companion object
中定义一个val变量,生成的会是一个私有变量但将getter方法生成到Companion
对象中,在java中访问须要调用伴生对象中的getter方法,给这个变量加上const修饰词会让生成的变量是公开静态变量,加上JvmFiled
注解效果相同,让变量能够在Java中直接访问,不用加上Companion
。
JvmName
:指定kotlin反编译的Java的方法名,字段名,类名等。
JvmMultifileClass
:将不一样的kotlin文件生成到一个java文件中,须要使用JvmName
指定生成的文件名,以后就能够在java中经过这个文件名访问不一样kotlin中代码。
JvmOverloads
:kotlin中的方法能够给入参设置默认值,这样在kotlin中调用的时候就能够不传入全部的值,可是在java中却不能这样调用,由于生成的java代码只有一个传入了所有参数的方法。使用Jvmoverloads
指定函数生成多个重载,就能够在Java中调用。通常须要在自定义view的时候使用,将构造函数重载成多个,不然在XML中使用这个view会抛出异常。
JvmPackageName
:指定从该文件生成.class文件的包名称。
JvmStatic
:想要在kotlin中定义静态方法是将这些方法放入伴生对象中,虽然在kotlin中能够经过调用静态方法那样经过类名调用,但反编译Java是经过定义一个静态内部类Companion,其中存放着伴生对象中的方法,类中持有一个这个内部静态类的实例对象来调用这些方法。给这些方法加上JvmStatic
注解以后,会把这些方法暴露成java的静态方法。若是标注的是静态属性,则会生成静态的getter和setter。
JvmSuppressWildcards
:在kotlin中,没有通配符(类如 ? extends Number
),能够直接进行泛型转换 val numberList : List<Number> = ArrayList<Int>()
,这种写法在Java中会报错。默认状况下,kotlin反编译Java的时候会在必要的状况下(1.类型不是最终类。2.不是函数的返回类型。)生成通配符。
类以下面生成的方法中,入参生成Number
的通配符List<? extends Number>
,另外一个入参List<String>
由于是最终类没有生成,返回值也没有生成。
某些状况下,若是想要更改默认的生成行为,可使用JvmSUppressWildcards
,此注释可传入一个布尔值(默认值是true),true表示生成类型不带通配符,false表示生成类型带通配符。
fun transformList(list : List<Number>, list : List<String>) : List<Number> // Kotlin
public List<Number> transformList(List<? extends Number> list, List<String> list) // Java
复制代码
JvmWildcard
:与上一个一致,至关于JvmSuppressWildcards(false)
,不一样的是能够作用的目标对象不一样,JvmWildcard
只能做用于类型参数,JvmSuppressWildcards
能够做用于类、函数、属性、类型参数。
JvmSynthetic
:在生成的Java字节码中加上'ACC_SYNTHETIC'标志,标记为合成,禁止方法在java中访问。
Throws
:kotlin中没有受检的异常(不强制要求必须处理异常),能够有选择的决定是否对异常进行处理,因此在kotlin中没有声明异常的throws关键字。使用注解Thorws会让生成的Java代码中进行throws,这样在java中调用的时候会检查这个异常。
Volatile
:充当java中vilatile关键字(多线程变量可见性)。
Transient
:充当java中transient关键字(不被序列化)。
Strictfp
:充当java中strictfp关键字(浮点数精度)。
Synchronized
:充当java中synchronized关键字(锁)。