Kotlin小结2(@Jvm方法研究)

研究下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特定的目标

你可能感兴趣的:(Kotlin小结2(@Jvm方法研究))