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