注解声明
注解是将元数据附加到代码的方法。要声明注解,请将 annotation 修饰符放在类的前面:
annotation class Fancy
注解的附加属性可以通过用元注解标注注解类来指定:
- @Target 指定可以用该注解标注的元素的可能的类型(类、函数、属性、表达式等);
- @Retention 指定该注解是否存储在编译后的 class 文件中,以及它在运行时能否通过反射可见 (默认都是 true);
- @Repeatable 允许在单个元素上多次使用相同的该注解;
- @MustBeDocumented 指定该注解是公有 API 的一部分,并且应该包含在生成的 API 文档中显示的类或方法的签名中。
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION) @Retention(AnnotationRetention.SOURCE) @MustBeDocumented annotation class Fancy
@JvmOverloads
/**
* Instructs the Kotlin compiler to generate overloads for this function that substitute default parameter values.
*
* If a method has N parameters and M of which have default values, M overloads are generated: the first one
* takes N-1 parameters (all but the last one that takes a default value), the second takes N-2 parameters, and so on.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
public annotation class JvmOverloads
@JvmOverloads 修饰有默认值的方法,那么在 Kotin 中会暴露多个重载方法。
@JvmOverloads fun(a: Int , b: Int){
}
上面的代码在 Java 中等于同时声明了两个方法
void fun(int a){}
void fun(int a,int b){}
同时,该注解解也可用在构造方法和静态方法上。
class CustomEditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null,
defStyle: Int = android.R.attr.editTextStyle) : EditText(context, attrs, defStyle){
在 Java 中相当于声明了以下构造函数
public class CustomEditText extends EditText {
public CustomEditText(Context context) {
this(context, null);
}
public CustomEditText(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
@JvmField
/**
* Instructs the Kotlin compiler not to generate getters/setters for this property and expose it as a field.
*
* 指示 kotlin 编译器不要为此属性生成 getters/setters, 并将其公开为字段。
*
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#instance-fields)
* for more information.
*/
@Target(AnnotationTarget.FIELD)
@Retention(AnnotationRetention.BINARY)
@MustBeDocumented
public actual annotation class JvmField
如果需要在 Java 中将 Kotlin 属性作为字段暴露,那就需要使用 @JvmField
注解对其标注。该字段将具有与底层属性相同的可见性。
class C(id: String) {
@JvmField val ID = id
}
// Java
class JavaClient {
public String getID(C c) {
return c.ID;
}
}
@JvmStatic
/**
* Specifies that an additional static method needs to be generated from this element if it's a function.
* If this element is a property, additional static getter/setter methods should be generated.
*
* 指定如果此元素是函数, 则需要从该元素生成其他静态方法。
* 如果此元素是一个属性, 则应生成其他静态 getter setter 方法。
*
* See the [Kotlin language documentation](https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-methods)
* for more information.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.RUNTIME)
@MustBeDocumented
public annotation class JvmStatic
Kotlin 还可以为 命名对象 或 伴生对象 中定义的函数 生成静态方法。如果你将这些函数标注为 @JvmStatic 的话,编译器既会在相应对象的类中生成静态方法,也会在对象自身中生成实例方法。
class C {
companion object {
@JvmStatic fun foo() {}
fun bar() {}
}
}
现在,foo() 在 Java 中是静态的:
C.foo(); // 没问题
C.Companion.foo(); // 保留实例方法
@JvmStatic
注解也可以应用于对象或伴生对象的属性,使其 getter 和 setter 方法在该对象或包含该伴生对象的类中是静态成员。