Kotlinの演算子は、Javaと似ている部分が多い一方で、安全性・明確性・可読性を最優先に設計されています。
そのため「Java経験者ほど誤解しやすいポイント」がいくつも存在します。
本記事では、Kotlinの演算子を単なる一覧ではなく、
- 実際にどう評価されるのか
- どこがJavaと決定的に違うのか
- 誤った理解をしやすい箇所はどこか
という観点で、正確に解説します。
算術演算子(+ – * / %)
Kotlinの算術演算子は基本的にJavaと同じ記号を使います。
val a = 10
val b = 3
a + b // 13
a - b // 7
a * b // 30
a / b // 3
a % b // 1
整数除算に注意
Kotlinでも 整数同士の除算は整数 になります。
10 / 3 // 3
10 / 3.0 // 3.333...
暗黙の型変換は存在しない
Kotlinでは数値の暗黙変換が禁止されています。
val d: Double = 10 // コンパイルエラー
val d: Double = 10.0 // OK
val d: Double = 10.toDouble() // OK
これは「安全性を犠牲にして便利さを取らない」というKotlinの設計思想によるものです。
代入演算子(+= -= *= /= %=)
var x = 10
x += 5
x -= 3
x *= 2
x /= 4
x %= 4
重要な注意点(誤解されやすい)
x += y は 常に x = x + y ではありません。
Kotlinでは次の順序で解決されます。
plusAssign(y)が定義されていれば、それを呼ぶ- 定義されていなければ
x = x + y(plus(y))に変換
つまり、型によっては 再代入ではなくオブジェクト内部の変更 が起こる場合があります。
この点はJavaよりも柔軟ですが、正しく理解しておく必要があります。
比較演算子(== と === の決定的な違い)
==:構造的等価(値の比較)
a == b
Kotlinの == は null安全 を含んだ比較です。
概念的には次のように評価されます。
a?.equals(b) ?: (b == null)
aがnullでも例外は発生しないequals()による値の比較
===:参照の等価(同一インスタンスか)
a === b
- メモリ上で同じオブジェクトかどうか
- Javaの
==に相当
例
val a = String(charArrayOf('t','e','s','t'))
val b = String(charArrayOf('t','e','s','t'))
a == b // true(値が同じ)
a === b // false(別インスタンス)
論理演算子(&& || !)
x && y
x || y
!x
短絡評価
KotlinもJavaと同様に短絡評価を行います。
false && function() // function()は呼ばれない
true || function() // function()は呼ばれない
インクリメント・デクリメント(++ / –)
var x = 10
++x // 前置
x++ // 後置
制約
valには使用不可- 式の評価順序はJavaと同じだが、可読性のため乱用は推奨されない
範囲演算子(Kotlinらしさの象徴)
1..5
1 until 5
5 downTo 1
1..10 step 2
for文との組み合わせ
for (i in 1..5) {
println(i)
}
範囲は IntRange などのオブジェクトとして扱われます。
in / !in 演算子(包含チェック)
val list = listOf(1, 2, 3)
2 in list
5 !in list
範囲・コレクション・文字列など、幅広い型で使用可能です。
null安全演算子(Kotlin最大の特徴)
安全呼び出し演算子 ?.
val name: String? = null
name?.length // null
Elvis演算子 ?:
val length = name?.length ?: 0
- 左が
nullなら右を返す - if文を書かずに安全なデフォルト処理が可能
強制アンラップ !!(非推奨)
name!!.length
nullの場合は 実行時例外- Javaとの境界やテストコード以外では極力避ける
型チェックとキャスト
型チェック(スマートキャスト)
if (obj is String) {
println(obj.length)
}
キャスト
val s = obj as String // 不一致で ClassCastException
val s = obj as? String // 不一致で null
as? は安全だが、戻り値は必ず nullable になる点に注意が必要です。
ビット演算(関数として提供)
Kotlinではビット演算は 記号ではなく関数 です。
a and b
a or b
a xor b
a shl 1
a shr 1
a ushr 1
a inv()
これらは infix 関数として定義されています。
演算子オーバーロード(上級者向け)
Kotlinでは特定の関数名を定義することで演算子を使えます。
data class Point(val x: Int, val y: Int) {
operator fun plus(other: Point): Point {
return Point(x + other.x, y + other.y)
}
}
val p3 = p1 + p2
主な対応関係
| 演算子 | 関数 |
|---|---|
| + | plus |
| – | minus |
| * | times |
| / | div |
| [] | get / set |
※ == は新しく定義するのではなく、equals をオーバーライドする点に注意。
まとめ
Kotlinの演算子は、
- null安全を前提
- 暗黙変換を排除
- 読みやすさを最優先
- DSLや拡張を意識した設計
という一貫した思想で作られています。
特に重要なのは次の4点です。
==と===の違い?.と?:- 範囲・
in as?による安全キャスト
これらを正しく理解できれば、Kotlinコードの品質と安全性は大きく向上します。
以上、Kotlinの演算子についてでした。
最後までお読みいただき、ありがとうございました。










