1. Javaのlong型の最大値とは?
Javaで扱えるlong型の最大値は、9223372036854775807です。
これは定数 Long.MAX_VALUE として定義されています。
まずは結論を確認します。
public class Main {
public static void main(String[] args) {
System.out.println(Long.MAX_VALUE);
}
}実行結果:
9223372036854775807つまり、Javaでlong型に格納できる正の最大値はこの数値になります。
1.1 long型の最大値は「9223372036854775807」
この値は数式で表すと次の通りです。
2^63 - 1なぜ「63」なのかが重要です。
- long型は 64ビット整数
- そのうち 1ビットは符号(正負)に使用
- 残り63ビットで数値を表現
そのため、
最大値 = 2^63 - 1となります。
※「ビット」とは0か1を表す最小単位のデータのことです。
1.2 なぜ64ビットなのに2^64-1ではないのか?
初心者が最も混乱しやすいポイントです。
Javaのlongは 符号付き整数(signed integer) です。
符号付きとは「正と負の両方を表せる整数」という意味です。
64ビットの内訳は:
- 1ビット → 符号
- 63ビット → 数値
そのため、正の最大値は
2^63 - 1になります。
「2^64 – 1」は**符号なし整数(unsigned)**の場合です。
Javaには unsigned long 型は存在しません。
⚠ よくある誤解
- × long最大値は 18446744073709551615
- ○ 正しくは 9223372036854775807
1.3 long型の最小値も確認しておこう
最大値とセットで覚えておくべきなのが最小値です。
System.out.println(Long.MIN_VALUE);実行結果:
-9223372036854775808数式では:
-2^63最大値よりも絶対値が1大きいのは、
Javaが 2の補数(two’s complement) という方式で整数を管理しているためです。
※2の補数とは、コンピュータが負の数を表現する標準的な仕組みです。
つまずきやすいポイント・注意点
2^64-1と勘違いする- unsigned longがあると思い込む
- 最大値を直接数値で覚えようとして桁を間違える
- int(32ビット)と混同する
特に、intの最大値(2147483647)と混同するミスは非常に多いです。
2. Javaでlongの最大値を取得する方法
longの最大値を扱う場合、数値を直接書くのではなく、定数を使うことが原則です。
ここでは安全かつ実務的な取得方法を解説します。
2.1 Long.MAX_VALUEを使う方法(推奨)
Javaでは、java.lang.Longクラスに最大値が定義されています。
long max = Long.MAX_VALUE;
System.out.println(max);実行結果:
9223372036854775807なぜ定数を使うべきか?
- 桁ミスを防げる
- 可読性が高い
- 型が明確
- 将来的な変更に強い(仕様変更は通常ないが安全)
特別なimportは不要です。java.langパッケージは自動的に読み込まれます。
2.2 数値を直接書く場合の注意点
最大値を直接記述することも可能です。
long max = 9223372036854775807L;ここで重要なのは 末尾の「L」 です。
なぜ「L」が必要なのか?
Javaでは整数リテラル(数値そのもの)は、
何も付けないと int型 として扱われます。
つまり:
long max = 9223372036854775807; // エラーこれはコンパイルエラーになります。
理由:
- intの範囲を超えている
- 明示的にlongであることを示していない
正しくは:
long max = 9223372036854775807L;⚠ 小文字の l は数字の 1 と見分けにくいため、大文字Lを推奨します。
2.3 ハードコーディングのリスク
「ハードコーディング」とは、数値を直接書くことです。
例:
if (value == 9223372036854775807L) {
// 処理
}問題点:
- 意味が伝わりにくい
- 保守性が低い
- 他の開発者が理解しづらい
推奨:
if (value == Long.MAX_VALUE) {
// 処理
}コードの意図が明確になります。
よくある失敗
- Lを付け忘れてコンパイルエラー
- int型の変数に代入しようとする
Long max = Long.MAX_VALUE;と書き、null扱いの可能性を考慮しない(ラッパークラス使用時)Math.pow(2,63)で計算しようとする(doubleになるため誤差発生)
※ Math.pow() はdouble型を返すため、整数の厳密値計算には不適切です。
3. long型が最大値を超えるとどうなる?(オーバーフロー)
long型は有限の範囲しか扱えません。
そのため、最大値を超えるとエラーではなく値が循環(ラップアラウンド)します。
これを「オーバーフロー(overflow)」と呼びます。
3.1 オーバーフローの実例
実際に確認します。
public class Main {
public static void main(String[] args) {
long max = Long.MAX_VALUE;
long overflow = max + 1;
System.out.println("最大値: " + max);
System.out.println("最大値 + 1: " + overflow);
}
}実行結果:
最大値: 9223372036854775807
最大値 + 1: -9223372036854775808最大値 + 1 が最小値になることが分かります。
これは異常ではなく、Java仕様通りの挙動です。
3.2 なぜエラーにならないのか?
Javaの整数型(int / long)は、
範囲超過時に例外を投げません。
理由:
- 固定ビット数(longは64ビット)
- 2の補数表現により値が循環
イメージ:
最大値 → +1 → 最小値
最小値 → -1 → 最大値コンピュータは単純にビットを計算するだけなので、
「範囲外」という概念は持ちません。
⚠ 初心者が混乱する点
- 「エラーになる」と思い込む
- 符号が突然反転してバグになる
3.3 オーバーフローを検出する方法
通常の加算では検出できません。
方法1:Math.addExact() を使う(推奨)
try {
long result = Math.addExact(Long.MAX_VALUE, 1);
} catch (ArithmeticException e) {
System.out.println("オーバーフローが発生しました");
}Math.addExact() は範囲超過時に ArithmeticException を投げます。
他にも:
Math.subtractExact()Math.multiplyExact()
があります。
3.4 範囲チェックを行う方法
加算前にチェックする方法もあります。
if (value > Long.MAX_VALUE - addValue) {
System.out.println("加算するとオーバーフローします");
}※ 実務ではこちらより addExact() の方が安全です。
3.5 BigIntegerを使う方法(上限なし)
longでは足りない場合は BigInteger を使用します。
import java.math.BigInteger;
BigInteger a = new BigInteger("9223372036854775807");
BigInteger b = BigInteger.ONE;
BigInteger result = a.add(b);
System.out.println(result);BigIntegerは桁数制限がありません。
ただし注意:
- longより処理速度は遅い
- メモリ消費が増える
- プリミティブ型ではない(オブジェクト型)
よくある失敗・注意点
- 金額計算でlongを使い、オーバーフローに気付かない
- ID生成で上限を考慮していない
- Math.powで計算して誤差を出す
- doubleに変換してから戻す(精度破壊)
特に金融系処理では致命的なバグになります。
4. 他の整数型との最大値比較
longの最大値を正しく理解するためには、他の整数型との違いも整理しておく必要があります。
Javaの整数型はビット数ごとに扱える範囲が明確に決まっています。
4.1 intとの違い
intは 32ビット符号付き整数 です。
System.out.println(Integer.MAX_VALUE);実行結果:
2147483647比較すると:
| 型 | ビット数 | 最大値 |
|---|---|---|
| int | 32ビット | 2,147,483,647 |
| long | 64ビット | 9,223,372,036,854,775,807 |
longはintの約43億倍の範囲を扱えます。
⚠ よくある失敗
- intで十分と思い込み、将来桁あふれ
- DBのBIGINTにintを対応させてしまう
4.2 short・byteとの比較
さらに小さい整数型も確認します。
System.out.println(Short.MAX_VALUE); // 32767
System.out.println(Byte.MAX_VALUE); // 127| 型 | ビット数 | 最大値 |
|---|---|---|
| byte | 8ビット | 127 |
| short | 16ビット | 32767 |
| int | 32ビット | 2147483647 |
| long | 64ビット | 9223372036854775807 |
用途の目安:
- byte → データ圧縮用途
- short → 小規模数値
- int → 通常の整数処理
- long → 大規模ID・タイムスタンプ
4.3 いつlongを使うべきか?
longを使う代表例:
- UNIXタイムスタンプ(ミリ秒単位)
- データベースのBIGINT列
- 大規模連番ID
- ファイルサイズ(バイト数)
例:
long timestamp = System.currentTimeMillis();System.currentTimeMillis() は long を返します。
これはミリ秒単位の値がintでは収まらないためです。
4.4 不必要にlongを使うリスク
longは8バイト使用します。
intは4バイトです。
大量データを扱う場合:
- メモリ消費が増加
- キャッシュ効率が低下
- パフォーマンス影響(環境により異なる)
そのため、
範囲が明確にintで収まるならintを使う
が基本原則です。
よくある失敗・注意点
- DBはBIGINTなのにJava側がint
- JSONの数値がlong前提なのにintで受け取る
- 型変換時に暗黙のキャストで精度損失
- Math.powの結果をlongに直接代入
特にAPI連携では型不一致によるバグが発生しやすいです。
5. longの最大値を扱う実務シーン
long最大値は単なる理論知識ではなく、実務でも重要です。
特に「桁あふれが致命的になる処理」では理解が必須です。
5.1 UNIXタイムスタンプ
Javaで現在時刻を取得する場合:
long now = System.currentTimeMillis();
System.out.println(now);System.currentTimeMillis() は1970年1月1日からの経過ミリ秒を返します。
もしintで受け取ると:
int now = (int) System.currentTimeMillis(); // 危険値が破壊されます(下位32ビットのみ保持)。
⚠ 注意点
- キャストによる桁切り捨て
- 2038年問題(int型タイムスタンプの限界)
- 秒単位とミリ秒単位の混同
longを使うことで2038年問題は回避できます。

5.2 データベース(BIGINT)との連携
多くのDBで BIGINT は64ビット整数です。
例:
CREATE TABLE users (
id BIGINT PRIMARY KEY
);Java側:
long id;もしintで受け取ると:
- データ破損
- 上限到達時に例外
- 将来的拡張不可
⚠ 実務で多い失敗
- 初期はintで足りる → 将来桁不足
- ORMで型マッピング誤り
- JSON変換時に数値精度問題(JavaScript側は53ビットまで安全)
5.3 ID生成と上限問題
分散ID(例:Snowflake系)ではlongが使われます。
例:
long id = generateId();理由:
- 64ビットで十分な空間
- 連番・時刻・マシンIDをビット分割可能
しかし、理論上はlongにも上限があります。
チェック例:
if (currentId == Long.MAX_VALUE) {
throw new IllegalStateException("ID上限に到達");
}通常は現実的に到達しませんが、設計上は考慮します。
5.4 ファイルサイズ計算
ファイルサイズ取得:
File file = new File("example.txt");
long size = file.length();巨大ファイルではintでは足りません。
⚠ 注意点
- longをintに変換しない
- 配列インデックスはint(ここで制限発生)
よくある実務ミス
- longをJSONで扱う際にJavaScript側で精度損失
- DB型変更時にJavaコード未修正
- 金額計算をlongで行い桁あふれ
- 上限を考慮せず永続的ID設計
6. long最大値に関するよくある誤解
longの最大値については、検索上でも誤解が非常に多い分野です。
ここでは混乱しやすいポイントを整理します。
6.1 unsigned longはJavaに存在しない
C/C++経験者が混乱しやすい点です。
Javaには
unsigned long 型は存在しませんlongは常に符号付き64ビット整数です。
そのため、扱える正の最大値は:
2^63 - 1です。
Java8以降では、以下のようなメソッドが追加されています:
Long.compareUnsigned(a, b);
Long.divideUnsigned(a, b);しかしこれは「unsigned演算を補助するメソッド」であり、型としてのunsigned longは存在しません。
6.2 最大値は2^64-1ではない
インターネット上で見かける誤情報:
18446744073709551615これは「符号なし64ビット整数」の最大値です。
Javaのlongは符号付きのため、
最大値は 9223372036854775807になります。
違いの整理:
| 種類 | 最大値 |
|---|---|
| 符号付き64ビット | 2^63 – 1 |
| 符号なし64ビット | 2^64 – 1 |
Javaは前者です。
6.3 BigIntegerとlongは別物
BigIntegerは上限なし整数です。
違い:
| 型 | 上限 | 性質 |
|---|---|---|
| long | 64ビット固定 | プリミティブ型 |
| BigInteger | 実質無制限 | オブジェクト型 |
BigIntegerは:
- メモリ消費が増える
- 計算速度が遅い
- equals比較が必要
longは:
- 高速
- 軽量
- 固定範囲
用途に応じて選択します。
6.4 Math.powで最大値を求めるのは危険
誤った例:
long max = (long) Math.pow(2, 63) - 1;問題点:
- Math.powはdoubleを返す
- doubleは53ビット精度
- 大きな整数で誤差発生
正しくは:
long max = Long.MAX_VALUE;よくある混乱まとめ
- unsigned longがあると思う
- 2^64-1と誤認
- Math.powで計算しようとする
- double経由で精度破壊
- BigIntegerとlongを混同
7. まとめ(最短復習)
ここまでの内容を、実務で必要なポイントに絞って整理します。
7.1 long最大値の結論
- 最大値:9223372036854775807
- 定数:Long.MAX_VALUE
- 数式:2^63 – 1
- 型:64ビット符号付き整数
確認コード:
System.out.println(Long.MAX_VALUE);7.2 必ず守るべき基本ルール
- 最大値は数値直書きではなく
Long.MAX_VALUEを使う - リテラルを書く場合は
Lを付ける - intと混同しない
- オーバーフローは例外にならない
7.3 オーバーフロー対策
安全に加算する場合:
Math.addExact(a, b);上限を超える可能性がある場合:
- BigIntegerを使用
- 範囲チェックを実装
7.4 実務での重要ポイント
- DBのBIGINTはlongで受ける
- UNIXタイムスタンプはlong
- JSON連携時は精度に注意
- ID設計では上限を意識する
7.5 最重要チェックリスト
- 2^64-1と勘違いしていないか
- unsigned longがあると思っていないか
- Math.powで計算していないか
- long→intへキャストしていないか
- 上限超過時の挙動を理解しているか
long最大値は単なる暗記項目ではなく、整数型の理解そのものを左右する重要概念です。
FAQ
Q1. Javaのlongの最大値はいくつですか?
9223372036854775807 です。
定数 Long.MAX_VALUE で取得できます。
Q2. longは何ビットですか?
64ビットの符号付き整数です。
1ビットが符号、残り63ビットが数値表現に使われます。
Q3. Long.MAX_VALUEを超えるとどうなりますか?
エラーにはなりません。
最小値(-9223372036854775808)に循環します。
System.out.println(Long.MAX_VALUE + 1);Q4. unsigned longはJavaにありますか?
型としては存在しません。
Java8以降にunsigned演算用メソッドはありますが、型はsignedのみです。
Q5. 最大値を安全に計算する方法はありますか?
直接計算せず、必ず:
Long.MAX_VALUEを使用してください。Math.pow()はdoubleを返すため不正確です。
Q6. intとlongはどちらを使うべきですか?
- 範囲が約21億以内 → int
- それ以上の可能性 → long
DBのBIGINTやタイムスタンプはlongを使います。
Q7. longは何桁まで扱えますか?
最大値は19桁です。9223372036854775807
Q8. longとBigIntegerの違いは?
- long → 固定64ビット、高速
- BigInteger → 上限なし、低速
範囲がlongで足りるならlongを使うのが原則です。


