Kotlinにおける as 演算子は、明示的な型キャストに使用されます。二つのバリエーションがあります: as と as?。一つは例外をスローし、もう一つはより安全です。このツールは、ポリモーフィズムやデータの移行、外部APIとのインタラクションに重要です。
Javaでは、型キャストに (TargetType)obj 演算子を使用し、エラー時に ClassCastException が発生します。Kotlinはこの概念を発展させ、安全なキャスト(as?)を追加し、nullabilityやランタイムエラーをより便利かつ明示的に管理できるようにしました。
大規模プロジェクトにおける厳格な型キャストは危険です:型が一致しない場合、プログラムはクラッシュしてしまいます(ClassCastException)。このような挙動を最小限に抑えることが重要で、サイレントエラーやNPEを避ける必要があります。エラーが処理されるべき状況と、単にnullを返すべき状況を質的に分けることが重要です。
Kotlinは二つの演算子を提供しています:
as:厳格な型キャストで、タイプが一致しない場合は ClassCastException をスローします。as?:安全なキャストで、キャストが不可能な場合は null を返します。val x: Any = "Hello, Kotlin!" val s1: String = x as String // Ok, x は String val s2: String? = x as? String // Ok, x は String val n: Int? = x as? Int // n = null, 安全なキャスト
as はエラーの際に ClassCastException をスローします。as? は null を返し、緊急のエラーを最小限に抑えます。'as' は常にランタイムで型をチェックしますか?
はい、キャストが不適合な型同士の場合、ClassCastException が発生します。ただし、Int と Float などのいくつかの暗黙的な変換に対しては、このキャストは発生しません — Kotlinではメソッド(toInt, toFloat)を通じてのイディオマティックな変換が行われます。
nullable 型を not-null 型に 'as' を使ってキャストできますか?
はい、しかし注意が必要です:もし値が null であれば、例外がスローされます。チェックなしで nullable 型から non-nullable 型へのキャストは、ランタイムエラーを引き起こす可能性があります。
val x: String? = null val y: String = x as String // ClassCastException をスローします!
'is' と 'as' の違いは何ですか?
'is' は型チェック演算子です。true/false を返し、型をキャストしません。'as' は型をキャストし、もし不可能な場合は例外をスローします(または 'as?' を使うと null を返します)。安全なキャストのために共に使用されることがよくあります:
if (x is String) { val s: String = x // スマートキャスト }
as を不注意に使用することにより、ClassCastException を引き起こすこと。データを解析するモジュールでは、すべてのオブジェクトが as を通じて解析されます。たとえば、 obj as Double。データが不正確な場合、アプリケーションは ClassCastException でクラッシュします。
利点:
欠点:
スマートキャスト(isによる)または安全なキャスト(as?)を使用します:
val price = (obj as? Double) ?: 0.0
利点:
欠点: