Kotlinにおける変数は、単に「値を保存するための仕組み」ではありません。
安全性・可読性・保守性を高めることを目的に、言語レベルで強い制約と思想が組み込まれています。
そのため、Kotlinの変数を正しく理解することは、Kotlinらしいコードを書くうえで最重要ポイントの一つです。
ここでは、基礎から実務で重要になる考え方まで、段階的に解説します。
Kotlinの変数宣言の基本
Kotlinでは、変数を宣言する際に var または val を使用します。
var count = 10
val name = "Kotlin"
var と val の違い
| 種類 | 再代入 | 意味 |
|---|---|---|
| var | 可能 | 可変変数 |
| val | 不可 | 読み取り専用変数 |
var x = 5
x = 10 // OK
val y = 5
y = 10 // コンパイルエラー
val は 一度代入したら別の値を再代入できない 変数です。
Kotlinではこの val を積極的に使うことが推奨されています。
基本方針としては
「まず val を使い、どうしても必要な場合のみ var にする」
という考え方が一般的です。
型推論(Type Inference)
Kotlinでは、多くの場合、型を明示しなくてもコンパイラが自動で型を推論します。
val age = 20 // Int
val price = 9.99 // Double
val flag = true // Boolean
もちろん、型を明示的に書くことも可能です。
val age: Int = 20
var message: String = "Hello"
型指定が必要になる場面
- 初期値をすぐに代入しない場合
- API仕様として型を明確にしたい場合
- 可読性や意図の明示を重視したい場合
var total: Int
total = 100
Kotlinの基本データ型
Kotlinでは、Int や Boolean などの型を クラスのように扱います。
文法上はプリミティブ型と参照型の違いを意識する必要はほとんどありません。
val score: Int = 90
val pi: Double = 3.14
val initial: Char = 'A'
ただし、JVM上では状況に応じて プリミティブ型に最適化されたり、ボクシングされたり します。
これは通常、開発者が意識する必要はありませんが、パフォーマンスに関わる場面では知識として重要です。
null安全と変数(Kotlin最大の特徴)
Kotlinでは、nullを許可するかどうかが型で明示されます。
nullを許可しない変数(デフォルト)
val text: String = "Hello"
text = null // コンパイルエラー
nullを許可する変数
val text: String? = null
| 型 | 意味 |
|---|---|
| String | null不可 |
| String? | null可 |
この仕組みにより、nullによる実行時エラーの多くをコンパイル時に防ぐことができます。
null安全演算子
セーフコール演算子 ?.
val length = text?.length
textが null →lengthは nulltextが非null → length が代入される
Elvis演算子 ?:
val length = text?.length ?: 0
null の場合のデフォルト値を指定できます。
強制アンラップ !!
val length = text!!.length
これは null の可能性を無視して強制的にアクセスする演算子です。
nullの場合は即座に例外が発生するため、実務では極力使用しません。
val と「オブジェクトの変更」
val は「再代入不可」を意味しますが、オブジェクト自体が不変であることを保証するものではありません。
val list = mutableListOf(1, 2, 3)
list.add(4) // OK
これは、
val→ 参照の再代入が不可MutableList→ 中身は変更可能
という2つの性質によるものです。
list = mutableListOf(9) // 再代入は不可
つまり、val は read-only reference(参照が読み取り専用) であり、オブジェクトの可変・不変とは別の概念です。
遅延初期化と変数
lateinit(var専用)
lateinit var userName: String
使用条件:
varのみ使用可能- nullable型には使えない
- JVMプリミティブにマップされる型には使えない
- 使用前に必ず初期化が必要
未初期化のままアクセスすると例外が発生します。
by lazy(val専用)
val config by lazy {
loadConfig()
}
- 初回アクセス時に初期化される
- デフォルトではスレッドセーフ(同期あり)
- 不要な初期化を避けたい場合に有効
状況によっては、スレッドセーフ性がオーバーヘッドになる点には注意が必要です。
定数(const val)
const val MAX_COUNT = 100
使用条件
- トップレベル
object内companion object内- プリミティブ型または String
class ApiConfig {
companion object {
const val TIMEOUT_MS = 3000
}
}
Javaの static final に相当します。
スコープと変数の有効範囲
Kotlinはブロックスコープを採用しています。
fun sample() {
val x = 10
if (x > 5) {
val y = 20
println(y)
}
// y はここでは使用不可
}
変数は 宣言されたブロック内でのみ有効 です。
実務でのベストプラクティス
- 可能な限り
valを使う - null を許可する変数は必要最小限にする
!!は原則使用しない- 変数のスコープはできるだけ狭く保つ
- 外部入力やI/O境界で nullable を受け取り、内部では non-null に寄せる
まとめ
Kotlinの変数は、
- 再代入の制御
- null安全
- 意図の明確化
- バグの予防
を言語仕様レベルで支援するために設計されています。
単に文法として覚えるのではなく、「なぜこう書くのか」「なぜこの制約があるのか」 を理解することで、Kotlinらしい、読みやすく壊れにくいコードが書けるようになります。
以上、Kotlinの変数についてでした。
最後までお読みいただき、ありがとうございました。









