深入kotlin - 枚举和注解
Posted 颐和园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入kotlin - 枚举和注解相关的知识,希望对你有一定的参考价值。
枚举
所谓枚举,就是实例个数有限的类。
定义
enum class Season
SPRING, SUMMER, AUTUMN, WINTER
既然是class,当然也可以有主构造器,通过主构造器为所有实例的 temperature 赋予不同的初始值:
enum class Season2(val temperature: Int)
SPRING(10), SUMMER(30),AUTUMN(30),WINTER(0)
当然也可以声明方法,而且可以在实例中重写方法:
enum class Season3
SPRING // 1
override fun getSeason():Season3 = SPRING
......
; // 2
abstract fun getSeason(): Season3 //3
- 重写枚举的抽象方法。
- 分号不可省略,用于分隔枚举的实例定义和方法定义。
- 枚举允许定义方法。
实例化
kotlin 的枚举基本上跟 java 一样,需要通过实例进行使用:
var seasons = Season.values() // 获取 Season 中全部实例
seasons.forEach println(it) // 打印:SPRING SUMMER AUTUMN WINTER
val season = Season.valueOf("SPRING") // 通过字符串(即枚举对象的 name)获得对应的枚举实例(即 SPRING)
println(season.name) // 打印:SPRING
注解
在 java 中使用 @Interface 可以定义注解。在 kotlin 中,使用 annotation class 定义注解:
annotation class MyAnnotation
元注解
元注解是修饰注解的注解,通常在定义注解时使用。
@Target
用于表示该注解可以应用于什么样的对象上,比如 CLASS、ANNOTATION_CLASS、PROPERTY、FIELD :
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.EXPRESSION, AnnotationTarget.VALUE_PARAMETER)
annotation class MyAnnotation
@Retention
用于注解的保存方式,有3个可能值:
- SOURCE 表示源代码,当编译以后注解就不存在了。
- BINARY 表示二进制。
- RUNTIME 表示运行时。
@Retention(AnnotationRetention.SOURCE)
annotation class MyAnnotation
@MustBeDocumented
表示该注解应该包含在所生成的文档中。
@MustBeDocumented
annotation class MyAnnotation
使用注解
在指定的 target 上使用即可。
@MyAnnotation // @Target 中包括 AnnotationTarget.CLASS
class MyClass
@MyAnnotation // @Target 中包括 AnnotationTarget.FUNCTION
fun method(@MyAnnotation a: Int):Int // @Target 中包括 AnnotationTarget.VALUE_PARAMETER(方法参数)
return (@MyAnnotation 10) // @Target 中包括AnnotationTarget.EXPRESSION
在主构造器上使用注解
在主构造器上使用注解时,constructor 关键字不可省略:
class MyClass @MyAnnotation constructor(a: Int)
在 set 方法上使用注解
同样在 set 方法上使用注解时,set 关键字不可省略:
class MyClass
var a: Int? = null
@MyAnnotation set // @Target 中包括 AnnotationTarget.PROPERTY_SETTER
注解的构造器
注解也可以定义构造方法及构造参数。构造参数所允许的类型包括:
- 8 种原生类型: Int, Long …
- String
- Class 类型(MyClass::class)
- 枚举
- 其他的注解
- 上述类型的数组
annotation class MyAnnotation(val str: String)
@MyAnnotation("hello")
class MyClass
annotation class MyAnnotation2(val str: String, val myAnnotation: MyAnnotation) // 1
@MyAnnotation2("test", MyAnnotation("welcome")) // 2
class MyClass2
- MyAnnotation2 的第二个构造参数是另外一个注解 MyAnnotation
- 使用 MyAnnotation2 时,第二个参数传入一个 MyAnnotation 实例
此外,注解参数不支持 optional,因为 JVM 不支持 null 形式存储注解的属性值,如果某个注解被用作其他注解的构造参数,那么其名字不需要以 @ 开头(见 1)。
如果注解构造参数使用 class 类型,那么要使用 kotlin 的 class(KClass) 而非 java class,kotlin 编译器会自动将其转换为 java class。
annotation class MyAnnotation(val arg1: KClass<*>, val arg2: KClass<out Any>)
@MyAnnotaion(String::class, Int::class)
class MyClass
KClass 位于 kotlin.reflect 包下,如果 IDE 不能自动导入,请手工导入。
注解使用处目标
在类的属性或者主构造参数上使用注解时,会存在多个 java 元素都可以通过对应的 kotlin 元素生成出来。因此在字节码中,会有多处位置生成注解,如果要指定具体的注解生成位置,可以通过“使用处目标“来避免这种歧义。
class MyClass(@field: MyAnnotation val arg1: String, // 1
@get: MyAnnotation val arg2: String, // 2
@param: MyAnnotation val arg3: String) // 3
- 生成注解时,在 java field 级别生成。
- 在 java get 方法上生成注解。
- 在 java 构造方法的参数处生成注解。
还可以在文件级别生成注解,此时注解位于文件第一行:
@file: JvmName("HelloKotlin") // 用指定文件名作为最终生成的字节码文件名,覆盖默认的文件名
package com.sample.kotlinstudy
import .....
Java 注解与 kotlin 注解兼容
二者是完全兼容的。
以上是关于深入kotlin - 枚举和注解的主要内容,如果未能解决你的问题,请参考以下文章