学习笔记-kotlin注解

注解本质上是一种代码的标签,做用的对象是代码。使用注解能够将额外的元数据关联到声明上,这些元数据能够被源代码工具和反射访问并作必定的操做。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 :标注能够做为注释目标的元素种类,也就是标注的注释能够做用于类或者变量等等种的哪些种类。传入值是一个变长参数:枚举类AnnotationTargetAnnotationTarget中定义了各类元素种类:工具

    • 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 :标记注释的保留期,传入一个枚举类AnnotationRetentionAnnotationRetention中定义了三个时期:

    • 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关键字(锁)。

相关文章
相关标签/搜索