メンバ変数、メソッドの引数、メソッド内の変数、固定値などJavaプログラムで利用する基本のデータ型について説明します。
Java は大きく二つの型に分類されます。
1つは、プリミテイブ型と呼ばれ、最も基本的なデータ型です。
もう一つは、プリミティブ型以外のオブジェクト全てを指します。プログラム用語として、参照型として定義されるています。
「プリミテイブ型」とは、プログラム言語が計算、文字操作など処理を実行するために開発者に用意された基本的なデータの種類です。
プログラミング用語として、「基本データ型」とも呼ばれます。
Javaプログラム言語でサーポートされているプリミティブ型は、8種類あります。
プリミティブ型は言語によって予め定義され、予約されたキーワードによって命名されます。
Oracle本家サイト「プリミティブ型」チュートリアルより引用
プリミティブ値は、他のプリミティブ値と状態を共有しません。
Javaプログラミング言語でサポートされている基本データ型は、8種類あります。
基本的な構成要素としてプログラミング言語によって提供されるデータ型である。
英語版WikiPedia「プリミティブ型」より引用
型 | ビット数 | デフォルト値 | 範囲(2進数表記) | 範囲(10進数表記) | 種類 |
---|---|---|---|---|---|
byte | 8 | 0 | -27~27-1 | -128~127 | 符号付き整数型 |
short | 16 | 0 | -215~215-1 | -32,768 ~32,767 | 符号付き整数型 |
int | 32 | 0 | -231~ 231-1 | -2,147,483,648~2,147,483,647 | 符号付き整数型 |
int(※) | 32 | ユーザ指定 (*Unsignedで 初期化するため) |
0~ 232-1 | 0~4,294,967,295 | 符号なし整数型(java8より) IntegerクラスのUnsigned用各種メソッドを利用 |
long | 64 | 0L | -263~ 263-1 | -9,223,372,036,854,775,808~ 9,223,372,036,854,775,807 |
符号付き整数型 |
long(※) | 64 | ユーザ指定 (*Unsignedで 初期化するため) |
0~264-1 | 0~18,446,744,073,709,551,615 | 符号なし整数型(java8より) LongクラスのUnsigned用各種メソッドを利用 |
float | 32 | 0.0f | (-1) 符号部×2指数部‐127 ×(1+仮数部) |
1.4E-45~3.4028235E38 | 単精度浮動小数点(32ビットIEEE 754) |
double | 64 | 0.0d | (-1) 符号部×2指数部‐1023 ×(1+仮数部) |
4.9E-324~1.7976931348623157E308 | 倍精度浮動小数点(32ビットIEEE 754) |
boolean | 1bitではない | false | true 又は false | 論理値型 | |
char | 16 | '¥u0000' | ¥u0000~¥uFFFF | 0~65,535の 16ビット符号なし整数型として |
文字(整数型) |
上記一覧表は、Oracle社のチュートリアルの文面から引用
Oracle社「データタイプ」より引用
この数値の範囲を覚えておく全て覚えておく必要はありません。byteの最大値が128-1とintの最大値が約21億という数値だけは頭の片隅に置いて下さい。
整数リテラル(0~9の数値)は、byte,short,int,longがあります。
longは、intのリテラルから作られています。
そのため、intの範囲を超える数値をlongで取り扱う際には、long型のリテラル文字(L)を利用します。
次頁で説明しますが、longを変数で定義する場合には、値の如何に関わらず、
long hoge = 12345678L
とlong型のリテラル文字を付与して下さい。
Javaソースファイル内にlong型のリテラル文字Lを付与した変数と付与していない変数の混同は、保守性を著しく低下させるためです。
Values of the integral types byte, short, int, and long can be created from int literals.
Oracle社「データタイプ」より引用
Values of type long that exceed the range of int can be created from long literals.
浮動小数点は、double型がデフォルトの数値リテラルとして認識されます。
そのため、doubleの範囲、floatの範囲の以下に問わず、
保守性の面からdoubleは「d」又は「D」をfloatには「f」又は「F」を接尾文字に付与して下さい。
2012年2月~2017年2月までの5年間のJavaのプリミティブ型のGoogle検索数総量をグラフにしました。
条件は、「java」と「基本データ型」を指定し、世界の国が対象です。
「int」は予想していた通りでしたが、「double」は予想外で、
「double」は英語として何かしらの別意味で数量に下駄がはいている可能性があります。
「byte」に関しても、「バイト数」の意味で検索されている可能性もあります。
良く利用される基本データ型の参考文献の1つとして捉えて下さい。
引用元以外の表記に関しては、私の2017年時点の主観で記述しています。
メモリの容量がシビアな環境化において、メモリの節約に役立ちます。
変数の範囲が限定されているという事実は、
ドキュメントの一種として役立つことがあります。引用元: Oracle社本家サイトデータ型より引用
byteは、JavaAPIのオブジェクト型のメソッドで引数及び戻り値で利用されている場合に利用します。
それ以外の個数、数値などの整数型として利用する局面は、IoTに代表される組み込み系のJavaや携帯アプリ開発などの
デバイスのメモリ、CPUの容量がシビアな環境化において、利用頻度が出てくると思います。
例えば業務要件でデータベースのテーブル項目の定義がNumber(1)と1桁の範囲だからJavaのDTOはbyteにするようなことはしません。
intを利用するのが保守性に優れたソースコードになります。
byteと同じく、メモリの容量がシビアな環境化において、メモリの節約に役立ちます。
引用元: Oracle社本家サイトデータ型より引用
shortは、JavaAPIのオブジェクト型のメソッドで引数及び戻り値で利用されている場合に利用します。
それ以外の個数、数値などの整数型として利用する局面は、IoTに代表される組み込み系のJavaや携帯アプリ開発などの
デバイスのメモリ、CPUの容量がシビアな環境化において、利用頻度が出てくると思います。
例えば業務要件でデータベースのテーブル項目の定義がNumber(4)と4桁の範囲だからJavaのDTOはshortにするようなことはしません。
intを利用するのが保守性に優れたソースコードになります。
詳細については、「Numberクラス」を参照してください。
Java8から,intのラッパークラスIntegerのcompareUnsigned, divideUnsignedのようなstaticメソッドを利用して、
符号付き整数型から符号なし整数型を利用できます。引用元: Oracle社本家サイトデータ型より引用
intは、凡そ21億までの数値を管理できます。
JavaAPIで一番引数や戻り値として多い基本データ型です。
その数値の範囲から多くの業務システムで利用されています。
ECサイト、SNSサイト、大企業の売上管理システムなどの日次、週次、月次バッチ処理等においては、
数量、金額等の扱うデータが21億以上を超える可能性が高いです。
その場合には、longを利用することになります。
intによって提供される値よりも広い範囲の値が必要な場合は、このデータ型を使用します。
Java8から,longのラッパークラスLongのcompareUnsigned, divideUnsignedのようなstaticメソッドを利用して、
符号付き整数型から符号なし整数型を利用できます。引用元: Oracle社本家サイトデータ型より引用
longは、標準で約922京、符号無しで1,844京(=18,446,744兆)の数値を表現できます。
金額であれば、日本の国家予算(平成28年)凡そ100兆円の9200年~1万8000年分を値に設定できます。
youtubeの世界一再生回数でも、27億回数も楽々値に設定できます。
longは、JavaAPIのオブジェクト型のメソッドで引数及び戻り値で利用されている場合に利用します。
また、 ECサイト、SNSサイト、大企業の売上管理システムなどの日次、週次、月次バッチ処理等(すなわち集計処理等)においては、
intでは桁溢れを起こすので、longを利用します。
byteおよびshortの推奨事項と同様に、浮動小数点数の大きな配列にメモリを保存する必要がある場合は、
float(doubleの代わりに)を使用します。
このデータ型は、通貨などの正確な値には使用しないでください。
そのためには、代わりにjava.math.BigDecimalクラスを使用する必要があります。
数値と文字列は、Javaプラットフォームによって提供されるBigDecimalおよびその他の有用なクラスをカバーします。引用元: Oracle社本家サイトデータ型より引用
正確に計算できる数の最大の整数値は 16,777,215(凡そ1600万)です。
限られた範囲での小数点計算時でIoTやモバイルデバイスなどのメモリ、CPUの容量が限られた分野で利用されます。
小数値の場合、このデータ型は通常はデフォルトの選択です。
前述のように、このデータ型は、通貨などの正確な値に使用されるべきではありません。
引用元: Oracle社本家サイトデータ型より引用
小数値の場合には、デフォルトの選択とあるように少数値の計算に精度が求められる分野で利用されます。
ビジネスシステムでは、doubleの利用される局面では、上記に推奨されるようにプリミティブ型のdoubleは用いず、
java.math.BigDeciamlクラスを利用するケースが多いです。
true / false条件を追跡する単純なフラグには、このデータ型を使用します。
このデータ型は1ビットの情報を表しますが、その「サイズ」は正確に定義されたものではありません。引用元: Oracle社本家サイトデータ型より引用
ビジネスロジックの判定などや複雑な判定条件をメソッド化して、戻り値として利用するケースが高いです。
DTOと呼ばれる一意の情報を格納するユーザが作成するオブジェクトでは、
プリミテイブ型のbooleanを利用するのではなく、ラッパークラスのBooleanを利用します。
数値計算などで型の選択に迷う場合には、整数はint、小数点はdoubleをデフォルトとして
オーバフロー(桁溢れ)が起きえる値の裏付けがある箇所には、適した基本データ型またはBigDecimal等に変更します。
設計段階で型を厳密に確定できることが、修正工数を鑑みると正しい姿かと思います。
しかしながら、実際の開発現場では設計者が漏れ無く型の定義を完璧にできているケースは少なく、
開発者もプログラミング時にこの計算処理は、「何のためにどのように利用されるために」計算しているのかを常に考え、
引数や戻り値のプリミティブ型の値の範囲を少し意識するのも大切です。
単体試験で計算処理のメソッドに対して、乖離値(取りうる値の最大、最小前後の値を試験データとする。)チェックを行うことで、
設計者及び開発者が見逃したプリミテイブ型の設計漏れ、間違いをを防ぐことが可能です。