Android
Kotlin
Adapter

JavaからKotlinに変換したコードが落ちるときがあるという話

More than 1 year has passed since last update.

JavaのコードをKotlinに変換

IntelliJ IDEA(およびAndroid Studio)にKotlinプラグインを入れると、メニューの[Code]に[Convert Java File to Kotlin File]というのがはえて、これでJavaのクラスを一気にKotlinに変換できます。

Nullable or NonNull

Javaには、NullableとNonNullの区別がないので、変換の際にコンバーターが考えてどっちかにしてくれるのですが、そのとき、なるべくNonNullにしようとするようです。

それでも、未初期化の非プリミティブ型の変数は、Nullableで初期値がnullになります。これは、それしかやりようがないですからしょうがないですね。

何処で落ちたか

さて、表題の変換後のコードが落ちる件ですが、AndroidのAdapterインターフェースのgetView()を実装しているところで頻発します。

Adapterインターフェース自体、使用頻度が高いのでやっかいです。

Hoge.java
class HogeAdapter extends BaseAdapter {
    ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ...
    }
}

これが、

Hoge.kt
class HogeAdapter : BaseAdapter() {
    ...

    override fun getView(position: Int, convertView: View, parent: ViewGroup): View {
        ...
    }
}

こんな感じに変換されます。

Androidアプリの開発者ならわかると思うのですが、このconvertViewはNullableです。
なので、実行すると、getView()に入ってくる前(ユーザコードを実行する前にKotlinが生成したコードでnullチェックが入ります)に落ちます。

変換後に修正してもいいのですが、ついうっかり修正するのを忘れてしまって、動作確認時に落ちて、「やっちまった。orz」となることもしばしばです。

そうならないために、

Hoge.java
class HogeAdapter extends BaseAdapter {
    ...

    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        ...
    }
}

というように、アノテーションをつけておくと、

Hoge.kt
class HogeAdapter : BaseAdapter() {
    ...

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        ...
    }
}

というように、ちゃんとNullableな型に変換されます。

まとめ

  • Kotlinを使うつもりがあるのなら、こまめに、@Nullable@NonNullアノテーションをつけておきましょう。
  • Nullableにしたくない変数は、キチンと初期化しておきましょう。