Kotlinのint型について

採用はこちら

Kotlinにおける Intは、単なる「32bit整数」ではありません。

Javaとの相互運用、JVM最適化、Nullable対応、コレクションとの関係などを正しく理解していないと、意図しないパフォーマンス低下やバグにつながることがあります。

本記事では、Kotlinを実務で使うエンジニア向けInt 型の仕様と内部挙動を正確に整理し、実践的な注意点まで含めて解説します。

目次

Kotlinの Int 型とは

Int は Kotlin が提供する 32ビット符号付き整数型です。

val a: Int = 10
  • ビット数:32bit
  • 表現できる範囲:-2,147,483,648 ~ 2,147,483,647

この数値範囲自体は Java の int と同じですが、Kotlinでは型としての扱い方が異なります。

Kotlinの Int と Javaの int の関係

Kotlinには「プリミティブ型」は存在しない

Kotlinの言語仕様上、intlong といった プリミティブ型は存在しません

代わりに IntLong などの Kotlinの数値型を使います。

ただしこれは「常にオブジェクトとして扱われる」という意味ではありません。

JVM上での実際の挙動(重要)

Kotlinコンパイラは、状況に応じて Intプリミティブ int または java.lang.Integer に変換・最適化します。

Kotlinコード上の型JVM上の実体
Int(非Nullable)int
Int?(Nullable)Integer
ジェネリクス(List<Int>など)Integer
val a: Int = 10      // JVMでは int
val b: Int? = 10    // JVMでは Integer

Kotlinの Int は「Kotlinの型」だが、JVM上では最適な形に変換される
この点を正しく理解することが非常に重要です。

数値リテラルと型推論

Kotlinでは、数値リテラルは文脈に応じて型推論されます。

val a = 10      // Int
val b = 10L     // Long
val c = 10.0    // Double

可読性のためのアンダースコア

val price = 1_000_000

アンダースコアは コンパイル時に無視されるため、性能への影響はありません。

演算ルールと整数除算

基本演算

val a = 10
val b = 3

val sum = a + b
val div = a / b   // 3(整数除算)

Int 同士の割り算は必ず整数除算になります。

小数結果が必要な場合

val div = a.toDouble() / b

意図しない整数除算は、実務で非常に多いバグ原因です。

オーバーフローとアンダーフロー

Kotlinの Intオーバーフローを検出しません

val max = Int.MAX_VALUE
println(max + 1)  // -2147483648

これは Java と同じく、2の補数によるラップアラウンドです。

実務上の対策

  • 計算量が増える可能性がある → Long を使う
  • 金額・桁数が重要 → 明示的に範囲チェック
  • 例外が欲しい → Javaの Math.addExact 等を利用

Int に用意されている定数・プロパティ

Int.MAX_VALUE
Int.MIN_VALUE
Int.SIZE_BITS    // 32
Int.SIZE_BYTES   // 4

マジックナンバーを避け、意味のある定数として使えるのは可読性・保守性の面で大きな利点です。

数値型の変換ルール(暗黙変換なし)

Kotlinでは 数値型の暗黙変換は行われません

val a: Int = 10
val b: Long = a   // コンパイルエラー

明示的に変換する

val b: Long = a.toLong()

利用可能な主な変換関数

toByte()
toShort()
toInt()
toLong()
toFloat()
toDouble()

これは 型安全性を高め、バグを防ぐための設計です。

Nullableな Int? の扱い

val a: Int? = null

安全呼び出し

val b = a?.plus(1)

Elvis演算子

val value = a ?: 0

JVM上の重要な注意点

  • Int? は基本的に Integer にボックス化される
  • 頻繁なループや大量データ処理では パフォーマンスコストになる可能性がある

IntArrayList<Int> の違い(実務で非常に重要)

JVM上の中身特徴
List<Int>Integerボックス化あり
Array<Int>Integerボックス化あり
IntArrayint高速・省メモリ
val arr = IntArray(5)
arr[0] = 10

数値を大量に扱う処理(集計、ループ、数値演算)では IntArray を優先的に検討すべきです。

演算子は関数として解釈される

Kotlinでは演算子は対応する関数呼び出しとして解釈されます。

val sum = a + b

これは概念的には以下と同等です。

val sum = a.plus(b)

この仕組みにより、ユーザー定義クラスでも演算子オーバーロードが可能になります。

===== の違い(Int? では特に注意)

val a: Int? = 1000
val b: Int? = 1000

println(a == b)   // true(値比較)
println(a === b)  // false になることが多い(参照比較)
  • == :値の比較(equals
  • ===:参照の比較

注意点

  • Int? はボックス化されるため === は参照比較になる
  • JVMのキャッシュや最適化により、=== の結果は 環境や状況で変わり得る
  • 値比較には必ず == を使う

実務でのベストプラクティスまとめ

  • 将来桁が増える可能性がある → Long を検討
  • Nullableは必要最小限に抑える
  • 大量数値処理 → IntArray
  • 除算は意図を明確に(整数か小数か)
  • === を数値比較に使わない

まとめ

  • Int はKotlinの32bit整数型
  • JVMでは状況に応じて int / Integer に変換される
  • Nullable・ジェネリクスではボックス化が発生
  • 暗黙の型変換は存在しない
  • 大量データでは IntArray が有利
  • オーバーフローは検出されない

以上、Kotlinのint型についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次