Kotlin 注脚

发布时间:2019-05-18  栏目:SQL  评论:0 Comments

Kotlin 的批注类详解及实例

Kotlin 的笺注完全合营 Java 的注释。

表明评释

  • 声称注脚

证明是将元数据附加到代码的艺术。要注脚注明,请将 annotation
修饰符放在类的日前:

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

表明的叠加属性能够透过用元注明标注注脚类来内定:

能够经过向注解类添日币注脚(meta-annotation)的法门来内定其余属性:
@Target 钦点这么些注明可被用来哪些要素(类, 函数, 属性, 表明式, 等等.);
@Retention 钦赐这么些声明的新闻是还是不是被保留到编译后的 class 文件中,
以及在运维时是或不是足以由此反
射访问到它;
@Repeatable 允许在单个元素上频仍利用同四个疏解;
@MustBeDocumented 代表那个注脚是开诚相见 API 的一片段, 在自动发出的 API
文书档案的类依旧函数具名
中, 应该包蕴那几个申明的音讯。

  1. @Target 钦点能够用
    该注明标注的要素的大概的项目(类、函数、属性、表达式等);
  2. @Retention 内定该申明是还是不是 存款和储蓄在编写翻译后的 class
    文件中,以及它在运营时是不是通过反射可知 (暗中同意都以 true);
  3. @Repeatable 允许 在单个成分上翻来覆去运用同1的该申明;
  4. @MustBeDocumented 钦定 该证明是国有 API 的1部分,并且应该包蕴在
    生成的 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)
    }
}

用法


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

参考
《Programming Kotlin》Stephen Samuel ,Stefan Bocutiu
《Kotlin in Action》Dmitry Jemerov,Svetlana Isakova

举例必要对类的主构造函数举办标注,则须要在构造函数注脚中增添 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() { }

1旦不钦定使用处目的,则根据正在使用的注明的 @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 中千篇一律,1个相当的情形是 value
参数;它的值没有需求显式名称内定。

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

壹旦 Java 中的 value 参数具备数组类型,它会化为 Kotlin 中的1个 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
}

 感激阅读,希望能帮忙到我们,谢谢大家对本站的协助!

你可能感兴趣的篇章:

留下评论

网站地图xml地图