objectのインスタンスを動的に取得する際にちょっとハマったのでメモ。
Kotlinは言語としてシングルトンをサポートしています。
書き方も非常にシンプルで、class
宣言の代わりにobject
を入れるだけ。
Hoge.kt
object Hoge {
...
}
インスタンスを取得するのもHoge()
で取れて簡単。
さて、今回はクラス名だけを外部パラメータから取得してこのobjectのインスタンスを動的に取得する方法です。
その前に、通常のclass
のインスタンスを動的に取得するにはどうすればいいでしょう。
Foo.kt
fun main(args:Array<String>) {
val name = args[0] // 実行時引数に"Hoge"が入っている想定
val instance = Class.forName(name).newInstance() as Hoge
}
JavaのClassを使う形で取れます。
がしかし、kotlinでobject宣言したクラスの名前を指定した場合、こんな感じで怒られます。
Exception in thread "main" java.lang.IllegalAccessException: Class FooKt can not access a member of class Hoge with modifiers "private"
objectはシングルトンのため、内部的にコンストラクタがprivateになっていて呼び出せないということのようです。
そこで、Kotlinのクラスを扱うことができるKClassを使います。
KClassにはobjectInstance
というプロパティが用意されていて、そこからobjectのインスタンスを取得できます。
Foo.kt
fun main(args:Array<String>) {
val name = args[0] // 実行時引数に"Hoge"が入っている想定
val clazz = Class.forName(name).kotlin // これでKClassが取得可能
val instance = clazz.objectInstance as Hoge
}
以上です。