Kotlin小結(jié)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個參數(shù)并且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的構(gòu)造方法

class TestView @JvmOverloads constructor(
    context: Context,
    attributeSet: AttributeSet? = null,
    defStyleAttr: Int = 0
) : FrameLayout(context, attributeSet, defStyleAttr)

這里需要注意,這個方法相當于實現(xiàn)了三個構(gòu)造方法

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);
}

注意兩者的區(qū)別,大部分情況下這兩種寫法是一樣的,但是有些類的默認構(gòu)造方法并不是這樣實現(xiàn)的,如WebView的兩個參數(shù)的構(gòu)造方法是有默認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代碼中調(diào)用的話就會被修改成javaFunction(),等同于方法

public void javaFunction()

3 @JvmStatic

該方法作用于kotlin object或者companion object中的方法或者屬性。如果作用于方法則會生成static方法,作用于屬性,則會生成static的get和set方法。java代碼調(diào)用時不用通過類名.INSTANCE方法來調(diào)用。意思很明顯不詳細探討

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代碼中定義的方法或?qū)傩缘膅et、set方法在java中不可訪問,多用于API設(shè)計人員需要從Java API中隱藏Kotlin特定的目標

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容