Kotlinのデフォルト値を使用した関数やコンストラクタをJavaから使用する際のtips

tl;dr

Kotlinコードで定義したデフォルト値を使用した関数,コンストラクタをJavaコードで使う事を想定する場合には@JvmOverloadsアノテーションをつける

@JvmOverloadsアノテーション

Kotlinの関数やコンストラクタの宣言で、以下のようにデフォルト値を使うと

class MyClass {
    fun myFunc(a: String = "", b: Int = 1, c: Boolean = true) {}
}

JavaからはMyClass#myFunc(String, int, boolean)のみ定義されているように見えます
変数b,cにはデフォルト値を使いつつMyClass#myFunc(String)の呼び出しを行いたいという場面では@JvmOverloadsアノテーションを使うことができます

@JvmOverloads
fun myFunc(a: String = "", b: Int = 1, c: Boolean = true) {}

Javaからは以下の4つが定義されているように見えます

  • myFunc()
  • myFunc(String)
  • myFunc(String, int)
  • myFunc(String, int, boolean)

@JvmOverloadsアノテーションをつける事で生成されるメソッドは、関数定義の後ろに宣言されているデフォルト値付き引数から順番に省略されます
今回の例ではc>b>aの順番に引数が消えた関数が生成されます

使用例: AndroidのCustomView

AndroidでCustomViewに以下のようなコンストラクタを生成する際に使うことができます

  • MyCustomView(Context)
  • MyCustomView(Context, AttributeSet)
  • MyCustomView(Context, AttributeSet, int)
class MyCustomView
@JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyleAttr: Int = 0)
    : View(context, attrs, defStyleAttr)

後ろにあるデフォルト値付き引数から順番に消えるため、リフレクションを使う場合など、引数の順番が大事な場合には定義の順番に気をつける必要があります

公式ドキュメント

JvmOverloads - Kotlin Programming Language