Kotlin 的注解类详解及实例

Kotlin 的注解类详解及实例

注解声明

注解是将元数据附加到代码的方法。要声明注解,请将 annotation 修饰符放在类的前面:

annotation class Fancy

注解的附加属性可以通过用元注解标注注解类来指定:

  1. @Target 指定可以用 该注解标注的元素的可能的类型(类、函数、属性、表达式等);
  2. @Retention 指定该注解是否 存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true);
  3. @Repeatable 允许 在单个元素上多次使用相同的该注解;
  4. @MustBeDocumented 指定 该注解是公有 API 的一部分,并且应该包含在 生成的 API 文档中显示的类或方法的签名中。

@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
        AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented

annotation class Fancy

用法

@Fancy class Foo {
  @Fancy fun baz(@Fancy foo: Int): Int {
    return (@Fancy 1)
  }
}

如果需要对类的主构造函数进行标注,则需要在构造函数声明中添加 constructor 关键字 ,并将注解添加到其前面:

class Foo @Inject constructor(dependency: MyDependency) {
  // ……
}

你也可以标注属性访问器:

class Foo {
  var x: MyDependency? = null
    @Inject set
}

构造函数

注解可以有接受参数的构造函数。

annotation class Special(val why: String)

@Special("example") class Foo {}

允许的参数类型有:

  1. 对应于 Java 原生类型的类型(Int、 Long等);
  2. 字符串;
  3. 类(Foo::class);
  4. 枚举;
  5. 其他注解;
  6. 上面已列类型的数组。

注解参数不能有可空类型,因为 JVM 不支持将 null 作为 注解属性的值存储。

如果注解用作另一个注解的参数,则其名称不以 @ 字符为前缀:

annotation class ReplaceWith(val expression: String)

annotation class Deprecated(
    val message: String,
    val replaceWith: ReplaceWith = ReplaceWith(""))
@Deprecated("This function is deprecated, use === instead", ReplaceWith("this === other"))

如果需要将一个类指定为注解的参数,请使用 Kotlin 类 (KClass)。Kotlin 编译器会 自动将其转换为 Java 类,以便 Java 代码能够正常看到该注解和参数 。

import kotlin.reflect.KClass

annotation class Ann(val arg1: KClass<*>, val arg2: KClass<out Any?>)

@Ann(String::class, Int::class) class MyClass

Lambda 表达式

注解也可以用于 lambda 表达式。它们会被应用于生成 lambda 表达式体的 invoke() 方法上。这对于像 Quasar这样的框架很有用,  该框架使用注解进行并发控制。

annotation class Suspendable

val f = @Suspendable { Fiber.sleep(10) }

注解使用处目标

当对属性或主构造函数参数进行标注时,从相应的 Kotlin 元素 生成的 Java 元素会有多个,因此在生成的 Java 字节码中该注解有多个可能位置 。如果要指定精确地指定应该如何生成该注解,请使用以下语法:

class Example(@field:Ann val foo,  // 标注 Java 字段
       @get:Ann val bar,   // 标注 Java getter
       @param:Ann val quux)  // 标注 Java 构造函数参数

可以使用相同的语法来标注整个文件。 要做到这一点,把带有目标 file 的注解放在 文件的顶层、package 指令之前或者在所有导入之前(如果文件在默认包中的话):

@file:JvmName("Foo")

package org.jetbrains.demo

如果你对同一目标有多个注解,那么可以这样来避免目标重复——在目标后面添加方括号 并将所有注解放在方括号内:

class Example {
   @set:[Inject VisibleForTesting]
   var collaborator: Collaborator
}

支持的使用处目标的完整列表为:

  1. file
  2. property(具有此目标的注解对 Java 不可见)
  3. field
  4. get(属性 getter)
  5. set(属性 setter)
  6. receiver(扩展函数或属性的接收者参数)
  7. param(构造函数参数)
  8. setparam(属性 setter 参数)
  9. delegate(为委托属性存储其委托实例的字段)

要标注扩展函数的接收者参数,请使用以下语法:

fun @receiver:Fancy String.myExtension() { }

如果不指定使用处目标,则根据正在使用的注解的 @Target 注解来选择目标 。如果有多个适用的目标,则使用以下列表中的第一个适用目标:

  • param
  • property
  • field

Java 注解

Java 注解与 Kotlin 100% 兼容:

import org.junit.Test
import org.junit.Assert.*
import org.junit.Rule
import org.junit.rules.*

class Tests {
  // 将 @Rule 注解应用于属性 getter
  @get:Rule val tempFolder = TemporaryFolder()

  @Test fun simple() {
    val f = tempFolder.newFile()
    assertEquals(42, getTheAnswer())
  }
}

因为 Java 编写的注解没有定义参数顺序,所以不能使用常规函数调用 语法来传递参数。相反,你需要使用命名参数语法。

// Java
public @interface Ann {
  int intValue();
  String stringValue();
}
// Kotlin
@Ann(intValue = 1, stringValue = "abc") class C

就像在 Java 中一样,一个特殊的情况是 value 参数;它的值无需显式名称指定。

// Java
public @interface AnnWithValue {
  String value();
}
// Kotlin
@AnnWithValue("abc") class C

如果 Java 中的 value 参数具有数组类型,它会成为 Kotlin 中的一个 vararg 参数:

// Java
public @interface AnnWithArrayValue {
  String[] value();
}
// Kotlin
@AnnWithArrayValue("abc", "foo", "bar") class C

对于具有数组类型的其他参数,你需要显式使用 arrayOf:

// Java
public @interface AnnWithArrayMethod {
  String[] names();
}
// Kotlin
@AnnWithArrayMethod(names = arrayOf("abc", "foo", "bar")) class C

注解实例的值会作为属性暴露给 Kotlin 代码。

// Java
public @interface Ann {
  int value();
}
// Kotlin
fun foo(ann: Ann) {
  val i = ann.value
}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 使用Kotlin开发Android应用教程

    使用Kotlin开发Android应用 1.Kotlin介绍 [Kotlin](https://kotlinlang.org/) Kotlin是一门基于JVM的编程语言,它正成长为Android开发中用于替代Java语言的继承者.Java是世界上使用最多的编程语言之一,当其他编程语言为更加便于开发者使用而不断进化时,Java并没有像预期那样及时跟进. Java缺失的很多特性在最新的修订版中逐渐覆盖到了,但Android开发者暂时还没能够使用它们.这就使得类似Kotlin这样的语言有了用武之地了:

  • Kotlin实现多函数接口的简化调用

    对于一个声明了多个方法的接口,我们使用的时候有时仅仅关注于几个关键方法,并不需要实现所有的.可是由于接口调用的语法限制,使得我们不得不在代码中也显示声明实现了那些我们不关心的方法.在Java中也有简化接口调用的方式,比如安卓中ViewPager监听页面切换时的接口PageChangeListener,官方提供了简单类: ViewPager.SimpleOnPageChangeListener来简化调用. 对于Kotlin来说,可以类似使用java的方式,来实现多函数接口的简化调用,只是要用到ob

  • Android Kotlin的使用及简单实例

    Android Kotlin的使用及简单实例 写在前面的话,作为一个不熬夜的人,一觉醒来发现Kotlin成为了Android的官方语言,可谓是大喜过望.为了趁热打铁,我决定提前三天放出原定本周日Release的文章.希望能及时让大家了解一下Kotlin. 相信很多开发人员,尤其是Android开发者都会或多或少听说过Kotlin,当然如果没有听过或者不熟悉也没有关系.因为本篇文章以及博客后期的内容会涉及到很多关于Kotlin的知识分享. 在写这篇文章前的一个多月,Flipboard中国的Andr

  • Kotlin开发Android应用实例详解

    Kotlin开发Android应用实例详解 相关文章:关于Kotlin语言的基础介绍: http://www.jb51.net/article/114086.htm 我们简单的知道了Kotlin这门新语言的优势,也接触了一些常见的语法及其简单的使用,相信你会对它有浓厚的兴趣,暂且理解为对它感兴趣吧,哈哈哈.那么,我们该如何在Android中应用这门新的语言呢?今天的这篇文章带你学习使用Kotlin开发Android应用,并对比我们传统语言Java,让你真真切切的感受到他的美和优雅. 配置 项目g

  • kotlin 官方学习教程之基础语法详解

    kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

  • Kotlin 开发环境详解及简单实例

    Hello Kotlin 在前段时间举办的Google I/O 2017上,Google宣布Kotlin成为Android官方的开发语言,这个最初发布于2011年的语言在短短的时间内就吸引了大量的开发者,而Google使得它进入了更多人的视线. Kotlin是一种开源的基于JVM的变成语言,由JetBeans公司开发(大概除了使用VS的.net开发者意外,都会或多或少听说或使用过IDEA吧),名字取自圣彼得堡附近的一个小岛(Koltin island). Kotlin是一种简单的语言,其主要目标

  • Kotlin实现静态方法

    工具类 全都是静态方法的情况 : class 类名 改为 object 类名 即可 package redwolf.com.moreimageupload import okhttp3.MultipartBody import java.io.File /** * @作者 RedWolf * @时间 2017/5/20 10:52 * @简介 MoreImageUtils.kt */ object MoreImageUtils { fun filesToMultipartBodyParts(fi

  • Kotlin开发的一些实用小技巧总结

    前言 随着Google I/O大会的召开,Google宣布将支持Kotlin作为Android的开发语言,最近关于Kotlin的文章.介绍就异常的活跃. 本文主要给大家介绍了关于Kotlin开发的一些实用小技巧,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 1.Lazy Loading(懒加载) 延迟加载有几个好处.延迟加载能让程序启动时间更快,因为加载被推迟到访问变量时. 这在使用 Kotlin 的 Android 应用程序而不是服务器应用程序中特别有用.对于 Androi

  • 用Kotlin实现Android点击事件的方法

    近期,Google宣布Kotlin成为了Android一级开发语言.于是就刚刚简单的研究了一下,查资料的时候发现现成的资料还是很少的,于是决定自己记录一下,方便以后查看,也供其他人一个参考. 在android中,点击事件大致分为三种写法: 1. 匿名内部类. 2. Activity实现全局OnClickListener接口. 3. 指定xml的onClick属性. 今天用Kotlin实现这三种方式实现点击事件 匿名内部类:这种方式最简单 override fun onCreate(savedIn

  • Kotlin 基础教程之数组容器

    Kotlin 基础教程之数组容器 Arrays Kotlin 标准库提供了arrayOf()创建数组, **ArrayOf创建特定类型数组 val array = arrayOf(1, 2, 3) val countries = arrayOf("UK", "Germany", "Italy") val numbers = intArrayOf(10, 20, 30) val array1 = Array(10, { k -> k * k

随机推荐