在Kotlin中@JvmOverloads注解的作用:指示Kotlin编译器为此函数生成替换默认参数值的重载。
如果一个方法有N个参数,其中M个具有默认值,则会生成M个重载。
第一个重载采用N-1个参数(最后一个采用默认值),第二个采用N-2个参数,依此类推。
因为在 Kotlin 中可以调用具有默认参数值的方法或者构造函数,但是在 Java 代码调用相应 Kotlin 代码却不行,及Java 代码不能调用Kotlin 中定义的具有默认参数的重载函数或构造函数。@JvmOverloads 就是用来解决这一问题的。
例子:
普通函数如下:
Kotlin方法参数无默认值:
@JvmOverloads fun testOverload(a: String, b: Int, c: Long) { }
转换成对应的Java代码是:
@JvmOverloads public static final void testOverload(@NotNull String a, int b, long c) { Intrinsics.checkParameterIsNotNull(a, "a"); }
Kotlin方法参数有一个默认值:
@JvmOverloads fun testOverload(a: String, b: Int, c: Long = 0L) { }
转换成对应的Java代码是:
@JvmOverloads public static final void testOverload(@NotNull String a, int b, long c) { Intrinsics.checkParameterIsNotNull(a, "a"); } // $FF: synthetic method public static void testOverload$default(String var0, int var1, long var2, int var4, Object var5) { if ((var4 & 4) != 0) { var2 = 0L; } testOverload(var0, var1, var2); } @JvmOverloads public static final void testOverload(@NotNull String a, int b) { testOverload$default(a, b, 0L, 4, (Object)null); }
Kotlin方法具有两个默认值:
@JvmOverloads fun testOverload(a: String, b: Int = 1, c: Long = 0L) { }
转换成Java代码如下:
@JvmOverloads public static final void testOverload(@NotNull String a, int b, long c) { Intrinsics.checkParameterIsNotNull(a, "a"); } // $FF: synthetic method public static void testOverload$default(String var0, int var1, long var2, int var4, Object var5) { if ((var4 & 2) != 0) { var1 = 1; } if ((var4 & 4) != 0) { var2 = 0L; } testOverload(var0, var1, var2); } @JvmOverloads public static final void testOverload(@NotNull String a, int b) { testOverload$default(a, b, 0L, 4, (Object)null); } @JvmOverloads public static final void testOverload(@NotNull String a) { testOverload$default(a, 0, 0L, 6, (Object)null); }
构造函数如下:
无默认参数值的构造函数:
open class MaxHeightRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : RelativeLayout(context, attrs, defStyleAttr) { }
转换成Java代码如下:
public class MaxHeightRelativeLayout extends RelativeLayout { @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context, @NotNull AttributeSet attrs, int defStyleAttr) { Intrinsics.checkParameterIsNotNull(context, "context"); Intrinsics.checkParameterIsNotNull(attrs, "attrs"); super(context, attrs, defStyleAttr); } }
具有一个默认值的构造函数:
open class MaxHeightRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int) : RelativeLayout(context, attrs, defStyleAttr) { }
转换成 Java代码如下:
public class MaxHeightRelativeLayout extends RelativeLayout { @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { Intrinsics.checkParameterIsNotNull(context, "context"); super(context, attrs, defStyleAttr); } // $FF: synthetic method public MaxHeightRelativeLayout(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) { if ((var4 & 2) != 0) { var2 = (AttributeSet)null; } this(var1, var2, var3); } @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context, int defStyleAttr) { this(context, (AttributeSet)null, defStyleAttr, 2, (DefaultConstructorMarker)null); } }
具有两个默认参数值的构造函数:
open class MaxHeightRelativeLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : RelativeLayout(context, attrs, defStyleAttr) { }
转Java代码如下:
public class MaxHeightRelativeLayout extends RelativeLayout { @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { Intrinsics.checkParameterIsNotNull(context, "context"); super(context, attrs, defStyleAttr); } // $FF: synthetic method public MaxHeightRelativeLayout(Context var1, AttributeSet var2, int var3, int var4, DefaultConstructorMarker var5) { if ((var4 & 2) != 0) { var2 = (AttributeSet)null; } if ((var4 & 4) != 0) { var3 = 0; } this(var1, var2, var3); } @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0, 4, (DefaultConstructorMarker)null); } @JvmOverloads public MaxHeightRelativeLayout(@NotNull Context context) { this(context, (AttributeSet)null, 0, 6, (DefaultConstructorMarker)null); } }