Android StudioでKotlinコードを記述していると、
「Type mismatch」というエラーが表示されることがあります。
このエラーは、Kotlinが期待しているデータ型と、
実際に渡している値のデータ型が一致していない場合に発生します。
原因としては、StringとIntの取り違え、
nullable型とnon-null型の違い、
関数の戻り値の型の不一致、
Listや配列の型の違いなど、さまざまなものがあります。
この記事では、Android StudioでKotlinの
「Type mismatch」が表示された場合に確認したい主な原因と、
基本的な解決方法を紹介します。
- 「Type mismatch」とは
- 原因1:StringとIntなど基本的な型が一致していない
- 原因2:IntとLong、FloatとDoubleなど数値型が一致していない
- 原因3:nullable型とnon-null型が一致していない
- 原因4:関数の引数の型が一致していない
- 原因5:関数の戻り値の型が一致していない
- 原因6:if式やwhen式の戻り値の型が合っていない
- 原因7:ListやMutableListの要素型が一致していない
- 原因8:配列の型が一致していない
- 原因9:ラムダ式の戻り値が想定と異なっている
- 原因10:AndroidのViewやContextなど必要な型が異なっている
- 原因11:View Bindingで取得したViewの型が想定と異なる
- 原因12:Jetpack Composeで引数の型が一致していない
- 型推論によって想定と違う型になっている場合
- エラーメッセージのRequiredとFoundを確認する
- 無理に型変換しない
- 「Type mismatch」が出たときの確認順序
- 具体的なエラー箇所を確認する
- まとめ
「Type mismatch」とは
Kotlinの「Type mismatch」は、
ある場所で必要とされている型と、
実際に指定された値の型が一致していないことを示すエラーです。
例えば、次のようなコードがあるとします。
val number: Int = "100"
このコードでは、
変数numberは
Int型として定義されています。
しかし、右辺の
"100"は文字列である
String型です。
そのため、Kotlinは
Int型が必要な場所にString型が指定されていると判断し、
「Type mismatch」を表示します。
「Type mismatch」が表示された場合は、
エラーメッセージ内の
「Required」と「Found」またはそれに相当する表示を確認すると、
必要な型と実際の型を特定しやすくなります。
原因1:StringとIntなど基本的な型が一致していない
よくある原因の1つが、
String、Int、Double、Booleanなどの基本的な型の取り違えです。
val age: Int = "20"
この場合、
ageにはInt型が必要ですが、
文字列の"20"が指定されています。
数値として扱いたい場合は、
次のようにInt型として記述します。
val age: Int = 20
String型の値をInt型へ変換する場合は、
toInt()などを使用します。
val text = "20"
val age: Int = text.toInt()
数値に変換できない文字列に対して
toInt()を実行すると例外が発生します。
入力値が不確実な場合は、
toIntOrNull()を使用する方法もあります。
原因2:IntとLong、FloatとDoubleなど数値型が一致していない
Kotlinでは、
数値型同士であっても自動的に別の型へ変換されない場合があります。
val number: Long = 100
数値リテラルでは状況に応じて適切に扱われる場合がありますが、
すでにInt型として定義された変数をLong型へそのまま代入することはできません。
val intValue: Int = 100
val longValue: Long = intValue
この場合は、
toLong()を使用して型を変換します。
val intValue: Int = 100
val longValue: Long = intValue.toLong()
同様に、
toDouble()、
toFloat()、
toInt()など、
必要な型に応じた変換を行います。
原因3:nullable型とnon-null型が一致していない
Kotlinでは、
nullを許可する型と許可しない型が明確に区別されています。
例えば、
Stringと
String?は異なる型として扱われます。
val text: String? = null
val message: String = text
textは
String?であり、
nullである可能性があります。
一方、
messageは
nullを許可しないString型です。
そのため、そのまま代入すると型が一致しません。
nullの場合に別の値を使用する場合は、
Elvis演算子を使用できます。
val text: String? = null
val message: String = text ?: "Default"
また、nullでないことを確認したうえで処理する方法もあります。
val text: String? = "Hello"
if (text != null) {
val message: String = text
}
!!を使用するとnullable型を強制的にnon-nullとして扱えますが、
実際にnullだった場合は例外が発生します。
原則として、nullチェックやElvis演算子などで安全に処理する方が適しています。
原因4:関数の引数の型が一致していない
関数へ渡している値の型が、
関数側で指定されている引数の型と異なる場合にも、
「Type mismatch」が発生します。
fun showNumber(number: Int) {
println(number)
}
showNumber("100")
showNumber()は
Int型の引数を必要としていますが、
String型の"100"を渡しているためエラーになります。
正しくは、Int型の値を渡します。
showNumber(100)
String型から変換する場合は、
必要に応じて型変換を行います。
原因5:関数の戻り値の型が一致していない
関数で指定した戻り値の型と、
実際にreturnしている値の型が異なる場合にも
「Type mismatch」が発生します。
fun getNumber(): Int {
return "100"
}
この関数では戻り値として
Intを指定していますが、
実際にはString型を返しています。
Int型を返す場合は次のようにします。
fun getNumber(): Int {
return 100
}
反対に文字列を返したい場合は、
関数の戻り値をString型に変更します。
原因6:if式やwhen式の戻り値の型が合っていない
Kotlinでは、
ifや
whenを式として使用できます。
そのため、それぞれの分岐から返される値の型によっては、
想定していた型と異なる結果になることがあります。
val result: Int = if (true) {
100
} else {
"error"
}
一方の分岐ではInt型、
もう一方ではString型を返しているため、
resultをInt型として扱うことができません。
同じ型を返すように修正します。
val result: Int = if (true) {
100
} else {
0
}
原因7:ListやMutableListの要素型が一致していない
ListやMutableListでは、
格納する要素の型も重要です。
val numbers: List<Int> = listOf("1", "2", "3")
左辺では
List<Int>を指定していますが、
右辺にはString型の値が格納されています。
Int型のListにする場合は、
次のように記述します。
val numbers: List<Int> = listOf(1, 2, 3)
String型のListとして扱いたい場合は、
型指定をList<String>に変更します。
原因8:配列の型が一致していない
Kotlinでは、
Array<Int>と
IntArrayなども別の型として扱われます。
使用しているAPIが特定の配列型を要求している場合、
別の形式の配列を渡すと型が一致しないことがあります。
val array: IntArray = intArrayOf(1, 2, 3)
エラーが表示された場合は、
関数やAPIが要求している配列の型と、
実際に作成している配列の型を確認します。
原因9:ラムダ式の戻り値が想定と異なっている
Kotlinではラムダ式を頻繁に使用しますが、
ラムダ式が返す値の型が期待されている型と異なる場合にも、
「Type mismatch」が発生することがあります。
val action: () -> Int = {
"Hello"
}
このラムダ式はInt型を返す必要がありますが、
実際にはString型を返しています。
Int型を返すように修正します。
val action: () -> Int = {
100
}
原因10:AndroidのViewやContextなど必要な型が異なっている
Android開発では、
Context、
Activity、
Fragment、
Viewなど、
Android固有の型を引数として渡す場面が多くあります。
このとき、APIが要求している型と異なるオブジェクトを渡すと、
「Type mismatch」が表示されることがあります。
例えば、Contextが必要な場所に別の種類のオブジェクトを渡している場合などです。
エラーが表示されたら、
呼び出しているコンストラクタや関数の引数定義を確認し、
どの型が要求されているかを確認します。
原因11:View Bindingで取得したViewの型が想定と異なる
View Bindingを使用している場合、
XMLで定義したViewの種類によって生成されるプロパティの型が決まります。
例えばXML側でTextViewとして定義されているViewを、
Button型として扱おうとすると型が一致しません。
View Binding関連でType mismatchが発生した場合は、
Kotlinコードだけでなく、
対応するXMLレイアウトでどのViewが定義されているかも確認してください。
原因12:Jetpack Composeで引数の型が一致していない
Jetpack Composeでも、
Composable関数へ渡す引数の型が異なることで
「Type mismatch」が発生することがあります。
例えば、
String型を要求する引数へInt型をそのまま渡している場合などです。
val count = 10
Text(text = count)
Text()の
textには文字列が必要なため、
必要に応じてString型へ変換します。
val count = 10
Text(text = count.toString())
型推論によって想定と違う型になっている場合
Kotlinでは、
明示的に型を書かなくても、
値から自動的に型が推論されます。
val value = 100
この場合、
valueは通常Int型として推論されます。
後から別の型として扱おうとすると、
Type mismatchにつながることがあります。
型が分かりにくい場合は、
一時的に明示的な型指定を追加すると、
問題を特定しやすくなります。
val value: Int = 100
エラーメッセージのRequiredとFoundを確認する
「Type mismatch」の原因を調べるときは、
Android Studioに表示されるエラーメッセージを確認します。
エラーメッセージには、
必要とされている型と、
実際に指定されている型が表示されることがあります。
Type mismatch.
Required: Int
Found: String
この場合は、
Int型が必要な場所にString型を渡していることが分かります。
どちらの型へ合わせるべきかを確認し、
変数の型を変更するか、
値を適切な型へ変換します。
無理に型変換しない
Type mismatchが発生すると、
とりあえず型キャストを追加して解決しようとする場合があります。
val value = data as String
しかし、
実際にはString型ではない値を強制的にキャストすると、
実行時に例外が発生する可能性があります。
型を変更する必要がある場合は、
まず元の値がどの型なのか、
なぜその型になっているのかを確認します。
必要に応じて、
安全なキャストである
as?を使用する方法もあります。
val value = data as? String
Type mismatchはコンパイラが型の不整合を検出している状態です。
無理にエラーを消すのではなく、
どちらの型が本来正しいのかを確認して修正することが重要です。
「Type mismatch」が出たときの確認順序
原因が分からない場合は、
次の順番で確認すると切り分けやすくなります。
- エラーメッセージで必要な型と実際の型を確認する
- 変数に指定している型を確認する
- 代入している値の型を確認する
- 関数の引数や戻り値の型を確認する
- nullable型とnon-null型の違いを確認する
- Int、Long、Float、Doubleなど数値型の違いを確認する
- ListやArrayなどの要素型を確認する
- 必要であれば適切な型変換を行う
- Android APIやライブラリが要求している型を確認する
- 強制キャストで無理に解決していないか確認する
具体的なエラー箇所を確認する
「Type mismatch」を解決するときは、
エラー名だけを見るのではなく、
どの値をどの型として扱おうとしているのかを確認することが重要です。
例:
Required: Int
Found: String
→ StringをIntへ変換する必要があるか確認
Required: String
Found: Int
→ toString()が必要か確認
Required: String
Found: String?
→ nullを許可する型かどうか確認
Required: Long
Found: Int
→ toLong()が必要か確認
List<Int>が必要
List<String>が渡されている
→ List内の要素型を確認
まとめ
Android StudioのKotlinで表示される
「Type mismatch」は、
必要とされているデータ型と、
実際に指定されている値のデータ型が一致していない場合に発生するエラーです。
特に多い原因は、
StringとIntなど基本的な型の違い、
数値型同士の違い、
nullable型とnon-null型の違い、
関数の引数や戻り値の型の不一致などです。
エラーが表示された場合は、
まずAndroid Studioのエラーメッセージから、
必要な型と実際の型を確認します。
そのうえで、
本来どちらの型を使用すべきなのかを判断し、
変数や関数の型を修正するか、
toInt()、
toLong()、
toString()などを使って適切に型変換します。
また、nullable型やコレクション、Android API、Jetpack Composeなどでは、
単純な基本型以外の型の違いによってType mismatchが発生することもあるため、
エラー箇所で要求されている型を確認しながら原因を切り分けることが重要です。
