4
1

More than 1 year has passed since last update.

textView.text = "文字列" はできるのに editText.text = "文字列" とできない理由とは

Posted at

経緯

俺「Javaを使っていたけど、これからはKotlinだ! まずは TextView での文字列の表示のあたりから。」
俺「textView.setText("文字列") っと。ほとんどJavaと変わらないけど、セミコロンが不要になったのはいいな」
Android Studio「セッターメソッドの呼び出しをプロパティ構文に置き換えられるよ!」
俺「なるほど!プロパティ構文で書けるのか、textView.text = "文字列" っと。いいね!」

俺「さて、じゃあ TextView の派生クラスである EditText の方も書き換えよう。 editText.text = "文字列" っと」
Kotlin「Type mismatch: inferred type is String but Editable! was expected
俺「え?」
Kotlin「Editableじゃないとダメです。String なら setText() を使って。」
俺「...」

理由

TextView#getText() の戻り値の型は CharSequence 1 だが、
EditText#getText() の戻り値の型は Editable 2 となっているため。

どういうことか

なぜセッター(setText())ではなく、ゲッター(getText())の話が出てきたかというと
Javaで定義されたゲッター/セッターをKotlinからプロパティ構文でアクセスする際、型の推論にはゲッターの戻り値の型が使用されるため。
(ちなみに、セッターしか無く対応するゲッターが無い場合にはプロパティ構文すら使えない)

メソッドのオーバーライド時に、戻り値の型を派生型(EditableCharSequence の派生型)に変えることは許されているので、こんな事態となってしまっている模様。

(´・ω・`)

それでもプロパティ構文が使いたい

TextView に明示的にキャストする

(editText as TextView).text = "文字列"

基底クラスにキャストするという一見「?」なコードにはなってしまう。

(別) Editable に変換する

editText.text = Editable.Factory.getInstance().newEditable("文字列")

インスタンス生成を伴うのでパフォーマンスが重視される場面では注意。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1