KotlinはAndroid開発の主要言語です。Google Android Docs (2025)によると、Androidの新規プロジェクトの95%以上がKotlinを使用しています。Kotlinの特性を理解する — data class、sealed class、コルーチン、scope functions — はAndroid開発者にとって必須の要件です。
重要ポイント
KotlinはJavaのクラス概念を拡張します。data class、sealed class、object、companion object — Javaには存在しないか、異なる方法で実装されている構造です。
data class — equals()、hashCode()、toString()、copy()、componentN()を自動生成するクラス。データモデル(DTO、Entity)に最適。要件:プライマリコンストラクタに少なくとも1つのパラメータ、val/var、open/sealed/inner不可。sealed class — 制限されたサブクラス階層を持つクラス。すべてのサブクラスはコンパイル時に既知で、同じファイルに宣言されます。sealed classでのwhen式はelseブランチを必要としません。sealed interface(Kotlin 1.9+) — sealed classと同様ですが、多重継承を許可します。object — シングルトン。objectキーワード(classではなく)で宣言。スレッドセーフな遅延初期化。companion object — クラスの静的メンバー。名前を持ちます(デフォルトはCompanion)。インターフェースを実装でき、extension functionsを持つことができます。
| タイプ | 説明 | 使用法 |
|---|---|---|
| data class | equals、hashCode、toString、copyの自動生成 | データモデル、DTO、Entity |
| sealed class | 制限された階層、whenチェック | 状態、結果、UI State |
| sealed interface | sealed class + 多重継承 | イベント、アクション(Kotlin 1.9+) |
| object | シングルトン(宣言的) | Factory、Utility、定数 |
| companion object | クラスの静的メンバー | Factory Method、静的定数 |
| enum class | 定数付き列挙 | 固定セットの状態 |
data class — 90%のモデルに。 sealed class — UI Stateと結果に。 object — シングルトンに。IT Sectrはすべての画面状態(Loading、Success、Error)にsealed classを推奨します。
Sealed class — 状態をモデル化するための強力なツール。例:UiState<T>とサブクラスLoading、Success(data: T)、Error(message: String)。when式はすべての状態の処理を保証します。Sealed interface — 多重実装が必要なイベントとアクション用。Value class(Kotlin 1.5+) — オーバーヘッドなしで単一の値をラップします。型安全な識別子に使用:@JvmInline value class UserId(val id: String)。
Extension Function — 継承なしで既存のクラスにメソッドを追加。fun String.isEmail(): Boolean。Extension Property — プロパティに対しても同様(バッキングフィールドなし)。Inline Function — 関数本体を呼び出し箇所に展開 — 呼び出しオーバーヘッドなし。ラムダを使用するhigher-order関数に使用。Higher-Order Function — 別の関数を受け取るか返す関数。Scope Functions — オブジェクトコンテキストを操作する5つの関数:let、run、with、apply、also。
let — コンテキストit、ラムダ結果を返す。null-safe呼び出しに使用(?.let {})。apply — コンテキストthis、コンテキストを返す。オブジェクト設定用。run — コンテキストthis、ラムダ結果を返す。コンテキストでの計算用。also — コンテキストit、コンテキストを返す。副作用用(ロギング)。with — extensionではない、コンテキストthis、ラムダ結果を返す。オブジェクトに対する一連の操作に。Lambda — 匿名関数。Destructuring Declaration — data classを変数に分解:val (name, age) = person。
Inline functionとreified — JVMでジェネリック型を保存する唯一の方法。使用例:型安全ビルダー(Gson.fromJson<T>())、型チェック(is T)、クラスの取得(T::class)。CrossinlineとNoinline — inline関数のラムダパラメータの修飾子。crossinline — non-local returnを禁止、noinline — 特定のラムダのインライン化を禁止。IT Sectrは型を扱う場合のみinline + reifiedを推奨します。通常のhigher-order関数では、inlineはバイトコードサイズを増やす可能性があります。
コルーチン — 非同期プログラミングのための軽量スレッド。スレッドをブロックせず — 一時停止(suspend)します。suspend function — スレッドをブロックせずに一時停止できる関数。コルーチンまたは別のsuspend関数からのみ呼び出せます。
CoroutineScope — コルーチンのスコープ。CoroutineContext(Job + Dispatcher)を含みます。lifecycleScope — Activity/Fragment用(Lifecycle-aware)。viewModelScope — ViewModel用(onCleared()で自動キャンセル)。GlobalScope — グローバルスコープ(プロダクションでは非推奨 — メモリリーク)。Dispatchers:Dispatchers.Main(UI)、Dispatchers.IO(ネットワーク/ディスク)、Dispatchers.Default(CPU負荷密集型)、Dispatchers.Unconfined(非推奨)。launch — コルーチンを開始:Job。async — 結果付きで開始:Deferred<T>。runBlocking — ブロッキングブリッジ。withContext — suspend関数内でDispatcherを切り替え。
// コルーチンの例:ViewModelでのデータ読み込み
class MainViewModel : ViewModel() {
private val _state = MutableStateFlow<UiState>(UiState.Loading)
val state: StateFlow<UiState> = _state.asStateFlow()
fun loadData() {
viewModelScope.launch {
_state.value = UiState.Loading
try {
val data = withContext(Dispatchers.IO) {
repository.fetchData()
}
_state.value = UiState.Success(data)
} catch (e: Exception) {
_state.value = UiState.Error(e.message)
}
}
}
}
// asyncを使った並列リクエスト
suspend fun loadCombinedData(): CombinedData = coroutineScope {
val users = async(Dispatchers.IO) { api.getUsers() }
val posts = async(Dispatchers.IO) { api.getPosts() }
CombinedData(users.await(), posts.await())
}viewModelScope.launch — ViewModelでの標準的なコルーチン起動。withContext(Dispatchers.IO) — ネットワークリクエストのためにIOスレッドに切り替え。Dispatchersはコルーチンが実行されるスレッドプールを決定します。IT SectrはViewModelにはviewModelScope、Activity/FragmentにはlifecycleScopeを推奨します。
reified — inline関数内の型修飾子。型の使用を可能にします:T::class、is T、as T。reifiedがない場合、JVMのジェネリクスは消去されます(型消去)。inline fun + reified — 型安全APIのための強力な組み合わせ。Destructuring Declaration — val (x, y) = point。data classおよびcomponentN()を持つ型で機能。typealias — 型エイリアス:typealias Callback = (String) -> Unit。lateinit — varの遅延初期化(依存性注入用)。スレッドセーフではない。lazy — valの遅延初期化(デフォルトでスレッドセーフ)。lazy(LazyThreadSafetyMode.NONE) — 同期なし。Extension functionとExtension property — 継承なしで機能を追加。Kotlinはextension functionsがユーティリティタスクの90%を解決する言語です。
Delegated Properties — getter/setterを別のオブジェクトに委譲。標準デリゲート:lazy、observable、vetoable、map。getValue/setValue演算子によるカスタムデリゲート。by — 委譲キーワード:val name by lazy { loadName() }。委譲プロパティはViewModelデリゲート(by viewModels())の基礎です。IT Sectrは遅延初期化にはlazy、変更の監視にはDelegates.observableを推奨します。
| 機能 | 説明 | 例 |
|---|---|---|
| reified | inlineでのジェネリック型保存 | inline fun <reified T> parse(): T |
| destructuring | data classの分解 | val (name, age) = person |
| typealias | 型エイリアス | typealias Orders = List<Order> |
| lateinit | varの遅延初期化 | lateinit var adapter: Adapter |
| lazy | valの遅延初期化 | val config by lazy { load() } |
| delegated | プロパティ委譲 | var x by Delegates.observable(0) |
reified — 型安全APIに。lazy — 遅延読み込みに。delegated properties — プロパティロジックの再利用に。IT Sectrは効果的なKotlin開発のためにこれらすべての機能を習得することを推奨します。
Flow — Kotlinのコールド非同期データストリーム。コレクターの要求に応じて値を発行。StateFlow — 単一の現在値を持つホットFlow。ViewModelでUI Stateに使用。SharedFlow — イベント用のホットFlow(ワンショットイベント)。flowOf、asFlow — コレクションからFlowを作成。catch、retry、debounce — 演算子。stateIn、shareIn — コールドFlowをホットに変換。IT SectrはUI StateにはStateFlow、イベント(Snackbar、ナビゲーション)にはSharedFlowを推奨します。
class SearchViewModel : ViewModel() {
private val _query = MutableStateFlow("")
val suggestions: StateFlow<List<String>> = _query
.debounce(300)
.filter { it.length >= 2 }
.flatMapLatest { repository.search(it) }
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
fun onQueryChanged(query: String) {
_query.value = query
}
}kotlinx.serialization — JSONシリアライゼーションのためのKotlinライブラリ。@Serializable — アノテーション。@SerialName — カスタムフィールド名。サポート:JSON、CBOR、ProtoBuf。Parcelize — Android Parcelableのための@Parcelize(手動実装不要)。Gson vs Moshi vs kotlinx:kotlinx.serialization — Kotlinファースト、コンパイルセーフ、リフレクション不要。Moshi — アノテーション + codegen。IT Sectrは新規プロジェクトにはkotlinx.serialization、既存プロジェクトにはMoshiを推奨します。
@Serializable
data class ApiResponse<T>(
val success: Boolean,
@SerialName("data") val data: T? = null,
val error: String? = null
)
@Serializable
data class User(
val id: Int,
val name: String,
val email: String
)
// デシリアライゼーション
val json = Json { ignoreUnknownKeys = true }
val response = json.decodeFromString<ApiResponse<List<User>>>(jsonString)
println("Users: ${response.data?.size ?: 0}")よくある質問
data class — データ用(equals/hashCode/copyの自動生成)。sealed class — 型階層用(whenでのチェック)。sealed interface — 多重継承対応版。
let、run、with、apply、also。コンテキスト(it vs this)と戻り値(result vs context)で区別。let — null安全性、apply — 設定、also — 副作用。
CoroutineScope — コルーチンのスコープ。lifecycleScope — Activity用、viewModelScope — ViewModel用。GlobalScope — 非推奨。
reified — inline関数での型保存。T::classやis Tを可能に。inline関数でのみ機能。
launch — 結果なし。async — 結果あり(Deferred)。runBlocking — main/test用ブロッキングブリッジ。withContext — Dispatcher切り替え。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。