研究下kotlin中以@Jvm开头的注解
1 @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.
*/
意思就是说如果一个方法中有N个参数并且M个有了默认值,就会有生成M个重载方法
如下
@JvmOverloads
fun testJvmOverload(args1: Int, args2: Int = 0, args3: Int = 1)
在java代码中会生成三个方法
public void testJvmOverload(int args1)
public void testJvmOverload(int args1,int args2)
public void testJvmOverload(int args1,int args2,int args3)
这个注解多用于Android中view的构造方法
class TestView @JvmOverloads constructor(
context: Context,
attributeSet: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attributeSet, defStyleAttr)
这里需要注意,这个方法相当于实现了三个构造方法
public TestView(Context context) {
super(context,null,0);
}
public TestView(Context context,AttributeSet attributeSet) {
super(context,attributeSet,0);
}
public TestView(Context context,AttributeSet attributeSet,int defStyleAttr){
super(context,attributeSet,defStyleAttr);
}
而不是
public TestView(Context context){
super(context);
}
public TestView(Context context,AttributeSet attributeSet){
super(context,attributeSet);
}
public TestView(Context context,AttributeSet attributeSet,int defStyleAttr){
super(context,attributeSet,defStyleAttr);
}
注意两者的区别,大部分情况下这两种写法是一样的,但是有些类的默认构造方法并不是这样实现的,如WebView的两个参数的构造方法是有默认style的
public WebView(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.webViewStyle);
}
2 @JvmName
该方法同样也是方法的注释,作用是重定义kotlin中的方法名在java中的显示
如下
@JvmName("javaFunction")
fun testJvmName()
在java代码中调用的话就会被修改成javaFunction(),等同于方法
public void javaFunction()
3 @JvmStatic
该方法作用于kotlin object或者companion object中的方法或者属性。如果作用于方法则会生成static方法,作用于属性,则会生成static的get和set方法。java代码调用时不用通过类名.INSTANCE方法来调用。意思很明显不详细探讨
4 @JvmPackageName
指定某个class的包名,用法跟@JvmName类似,只不过一个作用于类一个作用于方法
5 @JvmSynthetic
/**
* Sets `ACC_SYNTHETIC` flag on the annotated target in the Java bytecode.
*
* Synthetic targets become inaccessible for Java sources at compile time while still being accessible for Kotlin sources.
* Marking target as synthetic is a binary compatible change, already compiled Java code will be able to access such target.
*
* This annotation is intended for *rare cases* when API designer needs to hide Kotlin-specific target from Java API
* while keeping it a part of Kotlin API so the resulting API is idiomatic for both languages.
*/
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.FIELD)
@Retention(AnnotationRetention.SOURCE)
public actual annotation class JvmSynthetic
该方法可以使kotlin代码中定义的方法或属性的get、set方法在java中不可访问,多用于API设计人员需要从Java API中隐藏Kotlin特定的目标