深入kotlin枚举和注解

2022-08-12 09:45:36

枚举

所谓枚举,就是实例个数有限的类。

定义

enumclass Season{
	SPRING, SUMMER, AUTUMN, WINTER}

既然是class,当然也可以有主构造器,通过主构造器为所有实例的 temperature 赋予不同的初始值:

enumclassSeason2(val temperature: Int){SPRING(10),SUMMER(30),AUTUMN(30),WINTER(0)}

当然也可以声明方法,而且可以在实例中重写方法:

enumclass Season3{
	SPRING{// 1overridefungetSeason():Season3= SPRING}......;// 2abstractfungetSeason(): Season3//3}
  1. 重写枚举的抽象方法。
  2. 分号不可省略,用于分隔枚举的实例定义和方法定义。
  3. 枚举允许定义方法。

实例化

kotlin 的枚举基本上跟 java 一样,需要通过实例进行使用:

var seasons= Season.values()// 获取 Season 中全部实例
seasons.forEach{println(it)}// 打印:SPRING SUMMER AUTUMN WINTERval season= Season.valueOf("SPRING")// 通过字符串(即枚举对象的 name)获得对应的枚举实例(即 SPRING)println(season.name)// 打印:SPRING

注解

在 java 中使用 @Interface 可以定义注解。在 kotlin 中,使用 annotation class 定义注解:

annotationclass MyAnnotation

元注解

元注解是修饰注解的注解,通常在定义注解时使用。

@Target

用于表示该注解可以应用于什么样的对象上,比如 CLASS、ANNOTATION_CLASS、PROPERTY、FIELD :

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.EXPRESSION, AnnotationTarget.VALUE_PARAMETER)annotationclass MyAnnotation
@Retention

用于注解的保存方式,有3个可能值:

  • SOURCE 表示源代码,当编译以后注解就不存在了。
  • BINARY 表示二进制。
  • RUNTIME 表示运行时。
@Retention(AnnotationRetention.SOURCE)annotationclass MyAnnotation
@MustBeDocumented

表示该注解应该包含在所生成的文档中。

@MustBeDocumented
annotation class MyAnnotation

使用注解

在指定的 target 上使用即可。

@MyAnnotation// @Target 中包括 AnnotationTarget.CLASSclass MyClass{@MyAnnotation// @Target 中包括 AnnotationTarget.FUNCTIONfunmethod(@MyAnnotation a: Int):Int{// @Target 中包括 AnnotationTarget.VALUE_PARAMETER(方法参数)return(@MyAnnotation10)// @Target 中包括AnnotationTarget.EXPRESSION}}
在主构造器上使用注解

在主构造器上使用注解时,constructor 关键字不可省略:

class MyClass@MyAnnotationconstructor(a: Int){}
在 set 方法上使用注解

同样在 set 方法上使用注解时,set 关键字不可省略:

class MyClass{var a: Int?=null@MyAnnotationset// @Target 中包括 AnnotationTarget.PROPERTY_SETTER}

注解的构造器

注解也可以定义构造方法及构造参数。构造参数所允许的类型包括:

  • 8 种原生类型: Int, Long …
  • String
  • Class 类型(MyClass::class)
  • 枚举
  • 其他的注解
  • 上述类型的数组
annotationclassMyAnnotation(val str: String){}@MyAnnotation("hello")class MyClassannotationclassMyAnnotation2(val str: String,val myAnnotation: MyAnnotation)// 1@MyAnnotation2("test",MyAnnotation("welcome"))// 2class MyClass2
  1. MyAnnotation2 的第二个构造参数是另外一个注解 MyAnnotation
  2. 使用 MyAnnotation2 时,第二个参数传入一个 MyAnnotation 实例

此外,注解参数不支持 optional,因为 JVM 不支持 null 形式存储注解的属性值,如果某个注解被用作其他注解的构造参数,那么其名字不需要以 @ 开头(见 1)。

如果注解构造参数使用 class 类型,那么要使用 kotlin 的 class(KClass) 而非 java class,kotlin 编译器会自动将其转换为 java class。

annotationclassMyAnnotation(val arg1: KClass<*>,val arg2: KClass<out Any>)@MyAnnotaion(String::class, Int::class)class MyClass

KClass 位于 kotlin.reflect 包下,如果 IDE 不能自动导入,请手工导入。

注解使用处目标

在类的属性或者主构造参数上使用注解时,会存在多个 java 元素都可以通过对应的 kotlin 元素生成出来。因此在字节码中,会有多处位置生成注解,如果要指定具体的注解生成位置,可以通过“使用处目标“来避免这种歧义。

classMyClass(@field: MyAnnotationval arg1: String,// 1
              @get: MyAnnotationval arg2: String,// 2@param: MyAnnotationval arg3: String)// 3
  1. 生成注解时,在 java field 级别生成。
  2. 在 java get 方法上生成注解。
  3. 在 java 构造方法的参数处生成注解。

还可以在文件级别生成注解,此时注解位于文件第一行:

@file:JvmName("HelloKotlin")// 用指定文件名作为最终生成的字节码文件名,覆盖默认的文件名package com.sample.kotlinstudyimport.....

Java 注解与 kotlin 注解兼容

二者是完全兼容的。

  • 作者:颐和园
  • 原文链接:https://kmyhy.blog.csdn.net/article/details/122525482
    更新时间:2022-08-12 09:45:36