【Console Application】ファイルとデータベース 201【学習記】
ファイルとかデータベースの話🤤
→文字列になってるクラス名からインスタンス生成は Java のままでも通るけれど KClass でやると getDeclaredConstructor().newInstance() が objectInstance になって文字数が減るのでオススメ🤤
→ Kotlin のリフレクションは追加要素なので import だけではなく build.gradle への implementation 追記が要る
→ IntelliJ の提案をそのままやったら入れてくれるので深く考える必要は無いけど implementation 追加後の”更新《エディタ中の右上に出る見逃しやすい小さいボタンアイコンを押す》を忘れると build.gradle がエラーを吐いたまま reflect が使えなくて混乱するので注意
Reflection
さて、それじゃ今度はクラス名を得る方法とクラス名からインスタンスを作る方法を調べようね🤤
……… Java の String ………?🙄
確かこれ、 Kotlin としての String クラスとして取る方法が有った筈…🤔
以前少し調べてた時に KClass というので別れているとかそんな記事を見たから KClass って語を追加したら出てくるかな?🤤
……… Kotlin としてのクラスを取得する方法の様だけど…🤔
んんんん?🤔
リフレクションは特殊な仕掛けの要素だから省いてる…のかな?
普通そんな使わないだろうし確かにそうなんだけど…🙄
とりあえず名前は String になってるから K か J かは置いといてこのクラス名文字列からインスタンスを作る方法を先に探そうかな🤤
println(s::class.qualifiedName) // kotlin.String
何故か先に探してた Kotlin 名の取り方が出てくる等🙄
// 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
}
知りたかった物がずばり出てきた🤤
基本的には Java のコードとほぼ同じ様だけど forName() に .kotlin が付いてるから恐らく Kotlin では KClass の情報を追加で保持する様になっててそれが取り出せる、という事なんだと思う🤔
普通では利用されない機能ではあるものの、今回の汎用レコード化が要る学習用のライブラリでも有用な所を鑑みると手法自体は一般的って事なのかなと思う🤤
これに則って Class<*> の部分とか書き換えたらいいかな🤔
早速 .kotlin を足してみたところ🤤
型は調べなくても IDE が教えてくれる🤪
KClass に変更した時のインポート不足も IDE が提案してくれる🤤
すると当然 Class でのインスタンス生成方法は怒られるからこれを直したら一連の修正は完了かな🤔
何箇所かあるけど同じ修正だからそこは検索と置換で🤤
おお、珍しく IntelliJ が有能🤪
パッケージ追加が必要って記事が先に見つかってたけどそれも「やっとく?」って聞いてきてる😆
👇
然るべき所に追加されている事を確認🤤
でもこれ↑で先に見つけた記事と書式が随分違うお🤔
Kotlin 標準モジュール(要使用宣言)から reflect 選ぶよって事かしら、楽になったといえばその通りだけど多分この中に IntelliJ が標準で抱えてるバージョン数字込みの文字列を取り出せる配列かなんかになってるって事だろうかね🤔
Java ではインスタンスが正常に作れたかどうかを検査してるんだけど…これは rClass が Any? だから null かどうかを見れば良い…のかな?多分🤤
どうも違うっぽい🙄
<*> は <Any?> だからと思ったけどこれだと判定とれないぽい😞
ふむ、なる程、安全の方だから常に !=null なのか…🤔
失敗した時に何になってるのか調べる方法を探すぽ😑
………
出てこないけれど例外掴むのが早いかな?🤔
どの道この検査で例外を吐くから例外をメッセージ変えて吐き直すのが妥当かしら🤤
結局例外処理に変えたけど Java の方も try-catch にしないとまずい気がしてきた🙄
まぁとりあえずその辺りは備忘録に足すとして、やっとエラー無くなったしここはこれでヨシ🤤
次回は
main の移植に取り掛かれるかな🤤