Javaにおいて、データを扱う際に最も基本となるのがデータ型である。各種データ型の中でも、特に日常的に使用頻度が高いのが整数を扱うための「int型」である。本章では、int型の基礎知識を習得し、Javaプログラミングの基盤を固めることを目的とする。
intとは何か
int型とは、Javaにおける基本データ型(プリミティブ型)の一つであり、整数値を格納するために使用される。Javaが提供する整数型には、byte型、short型、int型、long型の4種類が存在するが、その中でもint型は汎用性に優れており、最も広く使用されている。
int number = 42; // 整数値42をint型変数numberに代入
System.out.println(number); // 42が出力される
上記のコードでは、int型変数「number」を宣言して値42を代入している。int型は計算機のCPUが最も効率的に処理できる整数型であるため、特別な理由がない限りはint型を選択することが推奨される。
Javaにおける整数リテラル(ソースコード上に直接記述される整数値)は、デフォルトでint型として扱われる。これは、Javaの設計者がint型を最も一般的な整数型として位置づけていることの証左である。
byte b = 10; // 10はint型リテラルだが、byte型の範囲内なので代入可能
long l = 10; // 10はint型リテラルだが、自動的にlong型に変換される
long bigNumber = 3000000000L; // int型の範囲を超える場合はL/lサフィックスが必要
整数計算の基本となるint型は、配列のインデックス指定や、ループカウンタ、様々な計算処理など、プログラムのあらゆる場面で活用される。整数型の中でのint型の立ち位置を理解することは、効率的なJavaプログラミングの第一歩である。
intのメモリサイズと表現範囲
int型は32ビット(4バイト)のメモリ領域を使用する。この領域サイズにより、int型が表現可能な値の範囲が決定される。具体的には、-2,147,483,648(-2^31)から2,147,483,647(2^31-1)までの整数を表現することが可能である。
int maxValue = Integer.MAX_VALUE; // int型の最大値(2,147,483,647)
int minValue = Integer.MIN_VALUE; // int型の最小値(-2,147,483,648)
System.out.println("最大値: " + maxValue);
System.out.println("最小値: " + minValue);
int型の表現範囲は、JavaVMの実装に依存せず、Java言語仕様により厳密に定義されている。このため、異なる環境でプログラムを実行しても同一の動作が保証される。
int型は表現範囲の上限または下限を超えると、オーバーフローまたはアンダーフローが発生する。この現象は、値が表現範囲の反対側に「回り込む」形で現れる。
int result = Integer.MAX_VALUE + 1; // オーバーフロー発生
System.out.println(result); // -2,147,483,648が出力される
int underflow = Integer.MIN_VALUE - 1; // アンダーフロー発生
System.out.println(underflow); // 2,147,483,647が出力される
上記の例では、int型の最大値に1を加算することでオーバーフローが発生し、結果として最小値が得られる。これは、符号付き32ビット整数の2の補数表現に基づく動作である。計算結果が表現範囲を超える可能性がある場合には、より大きな範囲を持つlong型の使用を検討するべきである。
int型のビット表現を理解することは、特にビット演算やメモリ最適化が求められる場面で重要となる。32ビットという大きさは、一般的な計算処理において十分な表現範囲と優れた処理効率を両立させるよう設計されている。
プリミティブ型とラッパークラス(Integer)の違い
Javaでは、int型のようなプリミティブ型に対応するラッパークラスとして、Integerクラスが提供されている。この二つは密接に関連しているが、重要な違いが存在する。
プリミティブ型のint型は値そのものを直接格納するが、ラッパークラスのIntegerはオブジェクトとして整数値を扱う。
int primitiveInt = 100; // プリミティブ型
Integer wrapperInt = Integer.valueOf(100); // ラッパークラス
// Java 5以降はオートボクシングにより以下のような記述も可能
Integer autoboxed = 100; // プリミティブ型からラッパークラスへの自動変換
int unboxed = autoboxed; // ラッパークラスからプリミティブ型への自動変換
Java 5以降で導入されたオートボクシング機能により、プリミティブ型とラッパークラスの相互変換が自動的に行われるようになったが、この変換にはわずかながらパフォーマンスコストがかかる。頻繁に行われるループ処理などではプリミティブ型を使用することでパフォーマンスを向上させることが可能である。
ラッパークラスであるIntegerは、単なる値の保持だけでなく、様々な便利なメソッドを提供している。
// 文字列から整数への変換
int parsed = Integer.parseInt("123");
// 2進数表現の文字列への変換
String binary = Integer.toBinaryString(42); // "101010"が得られる
// 値の比較
int comparison = Integer.compare(100, 200); // -1が得られる(100 < 200)
Integerクラスのメソッドは、特に文字列処理や数値変換などの場面で非常に有用である。また、Javaのコレクションフレームワーク(ArrayList、HashMapなど)ではプリミティブ型を直接扱えないため、これらを使用する場合にはラッパークラスが必要となる。
プリミティブ型のint型とラッパークラスのIntegerは、用途によって使い分けることが重要である。単純な数値計算や大量のデータ処理ではint型が効率的である一方、オブジェクト志向のプログラミングやコレクションの使用ではIntegerクラスが必要となる。近年のJava処理系は内部的な最適化が進んでいるが、パフォーマンスが重視される場面ではこの違いを意識することが求められる。
intの宣言と初期化
int型を使いこなすには、まず適切な宣言と初期化の方法を理解する必要がある。本章では、int型変数の宣言方法から様々な初期化テクニック、そして定数としての利用方法まで、基本から応用までを詳述する。
変数宣言の基本構文
Java言語におけるint型変数の宣言は、型名に続けて変数名を記述することで行われる。変数名は任意に設定できるが、Javaの命名規則に従う必要がある。
int count; // 最もシンプルな宣言方法
int userAge, systemCode; // 複数の変数をカンマ区切りで宣言可能
上記の例では、初期化せずに宣言のみを行っている。しかし、Javaでは変数はデフォルト値が自動的に設定されない(ローカル変数の場合)ため、初期化せずに使用しようとするとコンパイルエラーが発生する。これはJavaの安全性設計の一環である。
int uninitializedVariable;
// System.out.println(uninitializedVariable); // コンパイルエラー発生
Javaの変数名に関する規則として、英字(a-z, A-Z)、数字(0-9)、アンダースコア(_)、ドル記号($)が使用可能である。ただし、変数名の先頭は数字にできない点に注意が必要である。また、Javaの予約語(if, for, class など)は変数名として使用できない。
int validVariable; // 正しい変数名
int _underscoreStart; // アンダースコアで始まる変数名も有効
// int 1invalidStart; // 数字から始まるためコンパイルエラー
// int class; // 予約語のためコンパイルエラー
変数名の命名規則として、Javaではキャメルケースが広く採用されている。複合語では最初の単語は小文字で始め、以降の単語は大文字で始める方式である。
int userId; // キャメルケース(推奨される命名方法)
int user_id; // スネークケース(Javaでは一般的でない)
適切な変数名の選択は、コードの可読性と保守性に大きく影響する。変数の用途や役割を明確に示す名前を選ぶことが望ましい。例えば、int n;よりもint numberOfStudents;のように具体的な名前の方が、コードの理解が容易になる。
さまざまな初期化方法
int型変数を初期化する方法は複数存在する。最も一般的なのは、宣言と同時に値を代入する方法である。
int counter = 0; // 宣言と同時に初期化
int maxAttempts = 3, currentAttempt = 1; // 複数変数の同時初期化
値の代入には様々な方法がある。単純な数値リテラルだけでなく、計算式や他の変数の値、メソッドの戻り値なども使用可能である。
int sum = 10 + 20; // 計算式による初期化
int x = 5;
int y = x * 2; // 他の変数の値を使用した初期化
int randomValue = new java.util.Random().nextInt(100); // メソッドの戻り値による初期化
初期化の際に使用できる整数リテラルには、10進数だけでなく、2進数、8進数、16進数表記も可能である。
int decimal = 42; // 10進数表記
int binary = 0b101010; // 2進数表記(Java 7以降)
int octal = 052; // 8進数表記(先頭に0)
int hexadecimal = 0x2A; // 16進数表記(先頭に0x)
Java 7以降では、数値リテラルにアンダースコアを含めることができるようになった。これにて大きな数値の可読性が向上する。
int million = 1_000_000; // 桁区切りとしてアンダースコアを使用(1000000と同じ)
int creditCardNumber = 1234_5678_9012_3456; // 見やすいグループ分け
配列やコレクションからの値取得による初期化も一般的である。
int[] numbers = {10, 20, 30};
int firstElement = numbers[0]; // 配列の最初の要素で初期化
変数の初期化方法の選択は、コードの文脈や目的によって異なる。重要なのは、変数の役割を明確にし、適切な初期値を設定することである。
定数(final)としてのint
変更されるべきでない値を扱う場合には、finalキーワードを使用してint型の定数を宣言する。定数は一度初期化されると、その後値を変更することができない。
final int MAX_USERS = 100; // 定数の宣言と初期化
// MAX_USERS = 200; // コンパイルエラー - 定数の値は変更できない
定数名は、通常すべて大文字でアンダースコアによって単語を区切るスネークケースを使用するのが慣例である。これにて、コード内で定数であることが視覚的に識別しやすくなる。
final int CONNECTION_TIMEOUT = 30000; // ミリ秒単位のタイムアウト値
final int HTTP_OK = 200; // HTTPステータスコード
定数は初期化方法に応じて、コンパイル時定数と実行時定数に分類される。コンパイル時定数は、コンパイル時に値が決定する定数であり、リテラルや定数式で初期化される。実行時定数は、実行時に値が決定する定数である。
final int COMPILE_TIME_CONSTANT = 60 * 60; // コンパイル時に計算される
final int RUNTIME_CONSTANT = new java.util.Random().nextInt(100); // 実行時に値が決まる
クラス内で宣言されたstatic finalのint型変数は、クラス定数となる。これはクラスのすべてのインスタンスで共有される値であり、多くの場合、設定値やプログラム全体で使用される固定値を表現するために使用される。
public class Constants {
public static final int DAYS_IN_WEEK = 7;
public static final int MAX_PASSWORD_LENGTH = 20;
}
// 他のクラスからの参照方法
int daysLeft = Constants.DAYS_IN_WEEK - 2;
定数の適切な使用は、「マジックナンバー」(コード内に直接記述された意味の不明確な数値)を避け、コードの保守性と可読性を向上させる重要な手段である。また、プログラム内で同じ値が複数箇所で使用される場合、定数を使用することで一箇所での変更が全体に反映されるため、保守性が向上する。
intを使った計算と演算
int型を活用する上で最も基本となるのが、各種計算や演算処理である。本章では、基本的な算術演算から特殊な演算子、そしてビット演算まで、int型を用いた演算処理の全容を解説する。
基本的な四則演算
Javaにおけるint型の四則演算は、加算(+)、減算(-)、乗算(*)、除算(/)、剰余(%)の5つの演算子を用いて行われる。これらは日常的なプログラミングで最も頻繁に使用される演算である。
int a = 10;
int b = 3;
int sum = a + b; // 加算: 13
int difference = a - b; // 減算: 7
int product = a * b; // 乗算: 30
int quotient = a / b; // 除算: 3(小数部は切り捨て)
int remainder = a % b; // 剰余(余り): 1
int型の除算は、結果が整数に切り捨てられることに注意が必要である。これはJavaの仕様であり、小数部分は単純に破棄される。正確な除算結果が必要な場合は、float型やdouble型などの浮動小数点型を使用する必要がある。
int x = 10;
int y = 4;
int intDivision = x / y; // 結果は2(小数部切り捨て)
double doubleDivision = (double)x / y; // 結果は2.5(型変換により小数点以下が保持される)
剰余演算(%)は、ある数を別の数で割った余りを求める演算である。この演算子は、周期的な処理やある範囲内に値を制限する場合によく使用される。
int minute = 63;
int minuteInHour = minute % 60; // 1時間(60分)で割った余り: 3
四則演算において、ゼロによる除算や剰余の計算を行うと、実行時例外(java.lang.ArithmeticException)が発生する点に注意が必要である。
// int errorResult = 10 / 0; // ArithmeticExceptionが発生
複数の演算子を組み合わせる場合、演算の優先順位が適用される。かっこ()を使用することで、優先順位を明示的に指定することが可能である。
int result1 = 10 + 5 * 2; // 乗算が先に行われ、結果は20
int result2 = (10 + 5) * 2; // かっこ内が先に計算され、結果は30
int型の演算結果がint型の表現範囲を超える場合、オーバーフローが発生する。Javaでは、オーバーフローが発生しても例外は発生せず、値が「回り込む」形で表現範囲内の別の値になる。
int maxInt = Integer.MAX_VALUE; // 2147483647
int overflowResult = maxInt + 1; // -2147483648(オーバーフロー)
int underflowResult = Integer.MIN_VALUE - 1; // 2147483647(アンダーフロー)
大きな数値の計算や、オーバーフローを避ける必要がある場面では、long型やBigIntegerクラスの使用を検討するべきである。
インクリメント・デクリメント演算子
インクリメント(++)およびデクリメント(–)演算子は、変数の値を1だけ増加または減少させるための特殊な演算子である。これらは特にループカウンタなどで頻繁に使用される。
int count = 5;
count++; // 後置インクリメント: countの値が6になる
++count; // 前置インクリメント: countの値が7になる
int value = 10;
value--; // 後置デクリメント: valueの値が9になる
--value; // 前置デクリメント: valueの値が8になる
前置演算子(++count, –value)と後置演算子(count++, value–)の大きな違いは、式の評価順序にある。前置演算子は変数の値を変更してから式を評価し、後置演算子は式を評価してから変数の値を変更する。
int a = 5;
int b = ++a; // aが6に増加した後、bに6が代入される
System.out.println("a = " + a + ", b = " + b); // a = 6, b = 6
int c = 5;
int d = c++; // cの値5がdに代入された後、cが6に増加する
System.out.println("c = " + c + ", d = " + d); // c = 6, d = 5
インクリメント・デクリメント演算子は、コードを簡潔にする効果があるが、複雑な式の中で使用すると可読性が低下する場合がある。特に、同じ変数に対して複数回の増減操作を行う場合は注意が必要である。
int i = 0;
int j = ++i + i++ + ++i; // 可読性が低く、理解しづらい(避けるべき)
一般的に、単純な代入文や単独のステートメントとしての使用が推奨される。
int counter = 0;
counter++; // 明確で読みやすい使用法
ループ構文での使用も一般的である。
for (int i = 0; i < 10; i++) { // forループのカウンタ増加部分
System.out.println(i);
}
インクリメント・デクリメント演算子は単純な構文ながら、適切に使用することでコードの簡潔さと読みやすさを両立させることができる。
複合代入演算子の活用法
複合代入演算子は、算術演算と代入を一度に行うための簡潔な構文を提供する。基本的な算術演算子と組み合わせて使用され、コードの可読性と簡潔さを向上させる。
int value = 10;
value += 5; // value = value + 5 と同等: 15
value -= 3; // value = value - 3 と同等: 12
value *= 2; // value = value * 2 と同等: 24
value /= 4; // value = value / 4 と同等: 6
value %= 4; // value = value % 4 と同等: 2
複合代入演算子はビット演算子とも組み合わせることができる。
int flags = 0b1010; // 2進数で10進数の10
flags &= 0b1100; // AND: 0b1000(8)
flags |= 0b0001; // OR: 0b1001(9)
flags ^= 0b1111; // XOR: 0b0110(6)
flags <<= 2; // 左シフト: 0b011000(24)
flags >>= 1; // 右シフト: 0b01100(12)
複合代入演算子は、式の評価を一度だけ行う点で効率的である。特に複雑なオブジェクト参照や配列インデックスを使用する場合に有用である。
int[] data = {1, 2, 3, 4};
int index = calculateComplexIndex(); // 何らかの複雑な計算
// 複合代入演算子を使用しない場合
data[index] = data[index] + 10; // インデックス計算が2回実行される
// 複合代入演算子を使用する場合
data[index] += 10; // インデックス計算は1回のみ
複合代入演算子は、変数の値を段階的に変更する際に特に有用である。例えば、合計値の集計や複数のフラグビットの操作など、複数の操作を連続して行う場合に適している。
int total = 0;
total += item1; // 項目1を加算
total += item2; // 項目2を加算
total += item3; // 項目3を加算
複合代入演算子はint型以外の整数型や浮動小数点型でも使用できる。しかし、代入先の型に自動的に変換される点に注意が必要である。
byte b = 10;
// b = b + 5; // コンパイルエラー(結果がint型となるため)
b += 5; // 正常に動作(内部で適切な型変換が行われる)
このように、複合代入演算子は単なる省略記法以上の価値を持ち、適切に使用することでコードの効率性と可読性を向上させることができる。
ビット演算の基礎
int型は32ビットの整数を表現するため、個々のビットレベルでの操作が可能である。ビット演算は、フラグ管理やハードウェア制御、グラフィック処理など、低レベルな操作が必要な場面で特に有用である。
Javaでは、ビット単位のAND(&)、OR(|)、XOR(^)、NOT(~)、左シフト(<<)、右シフト(>>)、および符号なし右シフト(>>>)演算子が提供されている。
int a = 0b1100; // 2進数表記で12
int b = 0b1010; // 2進数表記で10
int andResult = a & b; // ビット単位AND: 0b1000(8)
int orResult = a | b; // ビット単位OR: 0b1110(14)
int xorResult = a ^ b; // ビット単位XOR: 0b0110(6)
int notResult = ~a; // ビット単位NOT: 0b...11110011(-13、32ビット全てが反転)
シフト演算子は、ビットを左または右に移動させる操作を行う。
int value = 0b00000001; // 1
int leftShift = value << 2; // 左シフト: 0b00000100(4)
int rightShift = 0b1000 >> 2; // 右シフト: 0b0010(2)
符号付き右シフト(>>)と符号なし右シフト(>>>)の違いは、最上位ビット(符号ビット)の扱いにある。符号付き右シフトでは符号ビットが保存されるが、符号なし右シフトでは常に0が挿入される。
int positiveNum = 0b01000000000000000000000000000000; // 1,073,741,824 (2^30)
int negativeNum = 0b10000000000000000000000000000000; // -2,147,483,648 (-(2^31))
// 符号付き右シフト
int signedShiftPos = positiveNum >> 1; // 約5億(先頭に0が入る)
int signedShiftNeg = negativeNum >> 1; // 約-10億(先頭に1が入る)
// 符号なし右シフト
int unsignedShiftPos = positiveNum >>> 1; // 約5億(先頭に0が入る)
int unsignedShiftNeg = negativeNum >>> 1; // 約10億(先頭に0が入る)
ビット演算は、フラグ(真偽値の集合)を効率的に管理するのに適している。一つのint変数で最大32個の真偽値を格納できる。
// フラグ用の定数定義
final int FLAG_READ = 0b0001; // 1
final int FLAG_WRITE = 0b0010; // 2
final int FLAG_EXECUTE = 0b0100; // 4
// フラグの設定
int permissions = 0;
permissions |= FLAG_READ; // 読み取り権限を付与
permissions |= FLAG_WRITE; // 書き込み権限を付与
// フラグのチェック
boolean canRead = (permissions & FLAG_READ) != 0; // true
boolean canExecute = (permissions & FLAG_EXECUTE) != 0; // false
// フラグの削除
permissions &= ~FLAG_WRITE; // 書き込み権限を削除
ビット演算を活用することで、メモリ使用量の最適化や処理速度の向上が図れる場面がある。ただし、コードの可読性が低下する可能性があるため、適切なコメントや説明変数の使用が推奨される。
intと他のデータ型の変換
プログラミングにおいて、異なるデータ型間の変換は頻繁に必要となる操作である。本章では、int型と他のデータ型との間の変換方法について詳細に解説する。
自動型変換(暗黙的キャスト)
Javaでは、より小さな型からより大きな型への変換は自動的に行われる。これを暗黙的キャスト(自動型変換)と呼ぶ。int型に関しては、byte型、short型からint型への変換が自動的に行われる。
byte byteValue = 100;
short shortValue = 1000;
int intValue;
intValue = byteValue; // byte型からint型への自動変換
System.out.println(intValue); // 100
intValue = shortValue; // short型からint型への自動変換
System.out.println(intValue); // 1000
自動型変換はデータの損失がない場合にのみ行われる。int型からより大きな表現範囲を持つlong型、float型、double型への変換も自動的に行われる。
int originalInt = 123456789;
long longValue = originalInt; // int型からlong型への自動変換
float floatValue = originalInt; // int型からfloat型への自動変換
double doubleValue = originalInt; // int型からdouble型への自動変換
System.out.println(longValue); // 123456789
System.out.println(floatValue); // 1.23456792E8(精度の問題により完全に等しくない)
System.out.println(doubleValue); // 1.23456789E8
注意すべき点として、int型からfloat型への自動変換では精度の問題が発生する可能性がある。floatは32ビットであり、int型の全ての値を正確に表現できるわけではない。特に大きな整数値の場合、小数点以下の精度が犠牲になる。
自動型変換は、複合型の計算においても適用される。異なる型の演算子を含む式では、より大きな型に合わせて自動的に変換される。
int i = 10;
long l = 400L;
double d = 3.14;
double result = i + l + d; // 全てdouble型に自動変換後、計算される
System.out.println(result); // 413.14
自動型変換は、Javaコンパイラによって安全性が保証されている操作である。データ損失のリスクがない場合にのみ適用されるため、安心して使用できる。
明示的キャスト
より大きな型からより小さな型への変換を行う場合、データの損失が発生する可能性があるため、自動的な変換は行われない。このような場合、プログラマが明示的にキャスト(型変換)を指示する必要がある。
double doubleValue = 10.5;
// int intValue = doubleValue; // コンパイルエラー
int intValue = (int) doubleValue; // 明示的キャスト
System.out.println(intValue); // 10(小数部分は切り捨てられる)
明示的キャストは、型名を括弧で囲んで値の前に配置することで実行される。この操作はデータの損失を引き起こす可能性があるため、慎重に使用する必要がある。
long longValue = 2147483650L; // int型の最大値を超える値
int intValue = (int) longValue; // 明示的キャスト
System.out.println(intValue); // 2(オーバーフロー発生)
上記の例では、long型の値がint型の表現範囲を超えているため、キャスト後の値は元の値とは大きく異なる。これはオーバーフローによるものであり、上位ビットが切り捨てられた結果である。2147483650Lは、int型の最大値(2147483647)を3だけ超えているため、キャスト後は2となる。これは2^32で割った余りに相当する。
複数のキャストを連続して行う場合、注意が必要である。キャストの順序によって結果が異なる場合がある。
double d = 10.5;
int i1 = (int) d; // 10(小数部分が切り捨てられる)
int i2 = (int) Math.round(d); // 11(四捨五入後に変換)
明示的キャストは、プログラマが意図的にデータの変換を行うことを示すため、コードの可読性向上にも寄与する。ただし、データ損失の可能性がある操作であるため、必要な場合にのみ使用すべきである。
特に重要なのは、キャストを行う前に値が目的の型の範囲内に収まるかどうかを確認することである。値が範囲外の場合、予期しない結果を引き起こす可能性がある。
long largeValue = 9223372036854775807L; // long型の最大値
// 範囲チェック後にキャスト
if (largeValue <= Integer.MAX_VALUE && largeValue >= Integer.MIN_VALUE) {
int safeInt = (int) largeValue;
System.out.println(safeInt);
} else {
System.out.println("値がint型の範囲を超えています");
}
このような範囲チェックを行うことで、安全な型変換が可能となる。
文字列とintの相互変換
プログラミングでは、文字列と数値型の間の変換が頻繁に必要となる。Javaでは、int型と文字列(String)の間の変換を行うための方法が複数提供されている。
int型から文字列への変換は、次のいくつかの方法で実現できる。
int value = 42;
// 方法1: String.valueOf()メソッドを使用
String str1 = String.valueOf(value);
// 方法2: Integer.toString()メソッドを使用
String str2 = Integer.toString(value);
// 方法3: 文字列連結演算子(+)を使用
String str3 = "" + value;
System.out.println(str1); // "42"
System.out.println(str2); // "42"
System.out.println(str3); // "42"
これらの方法はいずれも同じ結果を生成するが、パフォーマンス特性が異なる。一般的には、String.valueOf()またはInteger.toString()が推奨される。文字列連結演算子を使用する方法は簡潔だが、余分なStringオブジェクトが生成されるため効率が劣る。
Integer.toString()メソッドは、基数(進数)を指定して変換することも可能である。
int number = 42;
String binary = Integer.toString(number, 2); // 2進数表現: "101010"
String octal = Integer.toString(number, 8); // 8進数表現: "52"
String hexadecimal = Integer.toString(number, 16); // 16進数表現: "2a"
System.out.println(binary);
System.out.println(octal);
System.out.println(hexadecimal);
また、特定の進数表現に特化したメソッドも提供されている。
int value = 42;
String binary = Integer.toBinaryString(value); // "101010"
String octal = Integer.toOctalString(value); // "52"
String hex = Integer.toHexString(value); // "2a"
反対に、文字列からint型への変換には、Integer.parseInt()メソッドが最も一般的に使用される。
String numStr = "42";
int num = Integer.parseInt(numStr);
System.out.println(num); // 42
Integer.parseInt()メソッドも、基数(進数)を指定して変換することが可能である。
String binaryStr = "101010";
String octalStr = "52";
String hexStr = "2a";
int fromBinary = Integer.parseInt(binaryStr, 2); // 2進数から変換: 42
int fromOctal = Integer.parseInt(octalStr, 8); // 8進数から変換: 42
int fromHex = Integer.parseInt(hexStr, 16); // 16進数から変換: 42
System.out.println(fromBinary);
System.out.println(fromOctal);
System.out.println(fromHex);
文字列がint型に変換できない場合、NumberFormatExceptionが発生する。このため、変換前にバリデーションを行うか、例外処理を実装することが重要である。
String invalidStr = "42a";
try {
int value = Integer.parseInt(invalidStr);
System.out.println(value);
} catch (NumberFormatException e) {
System.out.println("無効な数値形式: " + invalidStr);
}
より安全な変換方法として、Integer.valueOf()メソッドも使用できる。このメソッドは内部でInteger.parseInt()を呼び出すが、結果をIntegerオブジェクトとして返す。
String validStr = "123";
Integer valueObj = Integer.valueOf(validStr);
int value = valueObj.intValue(); // Integerからintへのアンボクシング
文字列とint型の間の変換は、ユーザー入力の処理や、ファイルやデータベースからのデータ読み込みなど、多くの場面で必要となる。適切な変換方法を選択し、エラー処理を実装することで、堅牢なプログラムを構築することができる。
以上。