Javaにおけるプリミティブ型とは?プリミティブ型の種類8つとメリットを解説

Javaにおけるプリミティブ型とは?プリミティブ型の種類8つとメリットを解説のアイキャッチイメージ

Javaにおけるプリミティブ型とは


プリミティブ型とは、プログラム言語において基本と言うべき型です。

プリミティブ型として何をサポートしているかは言語によって違います。例えばPythonでは複素数を扱う128bitのcomplex型を標準でサポートしますが、Javaで複素数を扱うにはApache Commons Mathなどをインポートしないといけません。

Javaにおけるプリミティブ型とは、short型、byte型、long型、int型、double型、float型、char型、boolean型の8つの型を指します。Javaではこれらの型はライブラリをインポートせずとも型として宣言・使用できます。

この記事ではそれぞれの役割と特徴について解説していきます。また、プリミティブ型を参照型で書いた場合の挙動や、プリミティブ型と非常に似た性質を持つ(実態としては公式が用意したプリミティブ型の参照型とも言うべき)、ラッパークラスについても解説します。

参照型との違い

厳密に言うと参照型とプリミティブ型は対立する概念ではなく、プリミティブ型の参照型、自作型の参照型どちらも作成出来ることからも分かるように、両立する概念です。しかし多くの方が混乱されるため、ここでプリミティブ型の参照型について簡単に説明します。

参照型とはclass型、interface型、型変数、array型の4種類の総称です。多くの場合、プリミティブ型の参照型の使用する場合というのは配列として使用したいケースがほとんどです。

特に、文字を扱う場合は1文字だけを扱いたい場合というのはあまり少ないため、文字列を扱うchar[]の宣言を多く見かけます。c言語をすでにご存知の方はポインタをイメージすると分かりやすいでしょう。c言語の場合ではchar * nと宣言した際の挙動に非常に似ています。

変数を定義する際に一般にint nと書くのに対して、参照型ではint[] nという書き方をします。int[] n;n = 2;とするとコンパイルエラーとなります。

この場合は、n[0] = 2とするか、n = {2}とすると実行できるようになります。プリミティブ型を純粋に参照として使用したい場合は、後述のラッパークラスを使用する場合が一般的です。

ラッパークラスとの違い

ラッパークラスとは、名前の通りプリミティブ型をラッパーしているもので、それぞれに対応する8つの型があります。対応表は以下となります。

 プリミティブ型   ラッパークラス 
short Short
byte Byte
long Long
int Integer
double Double
float Float
char Character
bool Boolean

クラスなのでメソッドを持つことができ、実際にいくつかのメソッドを持っています。例えば数値であるintを文字型charに変換したい場合は(char)nなどとしないといけませんが、Integer型で定義すればnew Integer(2).toString()と、オブジェクト指向で書くことが出来ます。

また、賛否は分かれますが、プリミティブ型にない機能としてnullを代入することが出来ます。反面デメリットもあり、int型では32bitのみのメモリ確保であることに対し、Integer型はメソッドを持つ分、32bitよりも多くのメモリを使用します。

エンジニア転職のために覚えるべきプリミティブ型の種類8つ


Javaには以下の8つのプリミティブ型があります。大きく分類すると、整数(short, byte, long, int, char)、実数(double, float)、ブーリアン(boolean)の3種類です。

The primitive types (§4.2) are the boolean type and the numeric types. The numeric types are the integral types byte, short, int, long, and char, and the floating-point types float and double.

これらの変数について、各型で使用されるメモリサイズと主な用途、意外な落とし穴について説明します。ぜひ最後までご覧になってください。

1:short型

short型とは、16bitの整数です。-32768~32767 までの範囲の値を扱うことが出来ます。

しかし近年ではマシンのメモリも大きくなり、プロセッサの性能も大きいサイズの変数を扱うのに十分であることから、整数を扱う場合は後述のint型や、long型を多く見かけることになるでしょう。

2:byte型

byte型とは、8bitの整数です。値としては、-128~127 までを扱うことが出来ます。short型と同じく、整数として扱う場合はbyte型はあまり見かけることはありません。

byte型の主な用途としては、バイナリデータとbit長が同じであることから、バイナリデータやファイルの編集、変換などに用いられます。

3:long型

long型とは、64bitの整数です。値としては、-9223372036854775808~9223372036854775807 までを扱うことが出来ます。

実数のdouble型と同じく64bitですが、値の表現範囲はdouble型よりも狭くなっています。反面、実数型に対する整数型の特徴として、「丸め誤差が発生しない」、「演算が速い」といったメリットもあります。

4:int型

int型とは、32bitの整数です。-2147483648~2147483647 まで扱うことが出来ます。

ご覧の通り、10の9乗まで扱うことが出来ますが、金融計算などに使用する場合は注意が必要です。単位が円であった場合、10の9乗では約10億円までしか扱うことができないため、大きな取引などでは値がオーバーフローしてしまう恐れがあります。

そのため、あらかじめ大きい数値を扱うことが予想される場合には、前述のlongを使用しましょう。longであれば 10の18乗まで扱うことができるため、まずオーバーフローを心配することなく計算できます。

5:double型

double型とは、64bitの浮動小数点数です。有効数字約15桁、2の1023乗(10進数で約300桁)までの指数を扱うことが出来ます。

プリミティブ型の実数はこのdouble型とfloat型の2種類ありますが、実数を扱う場合にはdouble型を多く見かけます。

理由として、近年のプロセッサではfloatで確保されたメモリでも、演算領域に入る際にはdoubleの64bitに拡張されるため、パフォーマンス面でも特に違いがなくなるためです。

そのため、実数を宣言する場合にはdoubleを使用するようにしましょう。

6:float型

float型とは、32bitの浮動小数点数です。有効数字約7桁、2の127乗(10進数で約40桁)までの指数を扱うことが出来ます。前述の通り近年ではdouble型の使用が増えているため、あまり出番はありませんが、知識として覚えておくとよいでしょう。

7:char型

char型とは、16bitの文字型です。文字「列」ではないことに注意してください。文字列を扱う場合には前述の参照型を用いてchar[]と宣言しましょう。

なお、文字型には文字コードというものがあり、日本語版Windows環境ではデフォルトでMS932(Shift-JIS)に設定されています。MS932では「a」などの半角文字から「あ」などの全角文字、「亜」などの漢字や「÷」などの一部特殊文字まで対応しています。

格納される文字コードは環境毎にfile.encodingプロパティに設定されている値で決まることに注意が必要です。なお、文字コードを明示的に指定するにはString型で扱うならばoptional引数で個別に指定したり、System.setProperty()メソッドを使用することで環境全体を変更できます。

8:boolean型

boolean型とは、true/falseのデータを持つ真偽値型です。サイズに関して1bitと考える方もいますが、公式によるとサイズが定義されていません。

boolean: The boolean data type has only two possible values: true and false. Use this data type for simple flags that track true/false conditions. This data type represents one bit of information, but its “size” isn’t something that’s precisely defined.

特に意識をしてコーディングをすることはありませんが、知識として知っておくとよいでしょう。

プリミティブ型の特徴2つ


静的言語であり、およそ全ての型がクラスで作成されるJavaですが、プリミティブ型はクラスではないため、それらとは少し異なった2つの性質を持ちます。

特徴は、「変数のサイズが決まっている」、「メソッドを持たない」の2つです。それぞれ解説していきます。

変数のサイズが決まっている

プリミティブ型はそれぞれ先に述べた通り、1変数あたりのメモリ使用量が決まっています。

一方クラスは、たとえ公式が作成したものであったとしても、フィールドとメソッドを任意の数持てるため、コンパイルするまで1インスタンスあたりのメモリ使用量は判別できません。

そのためプリミティブ型はクラスに比べ、関数やメソッドのメモリ使用量がコンパイル以前でも推定できる他、サイズが国際規格で決まっていることで、近年のプロセッサはプリミティブ型に最適化されており、高いパフォーマンスが発揮できるようになっているなどのメリットを持ちます。

メソッドを持たない

Javaにおけるプリミティブ型はメソッドを持ちません。これもまた、プリミティブ型がクラスではないためです。

比較のため、intのラッパークラスであるIntegerを用いて例を挙げます。プリミティブ型であるint<では数値を比較する際int n = 2; n.equals(2);などといった書き方が出来ません。intはequals()はもちろんその他一切のメソッドを持たないためです。 Integerの場合は、Integer n = new Integer(2); n.equals(2);とできます。またintの場合は、n == 2;とすることでブーリアン値を得ることが出来ます。

プリミティブ型のメリット5つ


クラスと違い変数のサイズが決まっており、メソッドを持たないプリミティブ型ですが、クラスを使用する場合に比べ以下の5つのメリットがあります。

大きく、パフォーマンスが向上すること(メモリ節約、GC非対象、処理時間軽減)、バグを発生させにくいこと(可読性向上、null代入不可)の2つに分類することが出来ます。

1:メモリの使用量が減る

プリミティブ型は変数の表現に必要な最低限のメモリしか持ちません。例えばintは32bitですが、この型の表現の範囲は-2147483648~2147483647であり、これは2の31乗と正負の1bitから構成されるためです。

つまり、プリミティブ型が変数をシンプルに表現できる方法であるということです。

2:ガベージコレクションの対象にならない

例えばラッパークラスを使用した場合、変数はオブジェクトであるためヒープ領域に確保され、ガベージコレクションの対象となります。これはパフォーマンスに影響を与える他、意図せず誤った参照が残ってしまった場合バグの原因ともなり得ます。

一方、プリミティブ型ではスタック領域に確保されガベージコレクションの対象とならず、ローカル変数の場合は関数を抜ければ自動的に削除されます。

3:処理時間が短縮される

先のメモリ使用量が少ないこと、ガベージコレクションの対象にならないことと関係しますが、プリミティブ型を使用することでパフォーマンスを大きく向上させることが出来ます。

これはプリミティブ型の変数はスタック領域に確保されるため、関数を抜けると自動的に削除されることや、メモリサイズが確定していることからコンパイラが最適化しやすいことが関係します。

4:数値の比較に使えるコードが便利

ラッパークラスではInteger a = new Integer(2); Integer b = new Integer(2); a==b;とすると結果がfalseとなります。これは値を比較しているためではなく、同じインスタンスかどうかを判定しているためです。

このように、ラッパークラスでは直感に反する結果となってしまいますが、プリミティブ型ではint a = 2; int b = 2; a==bと計算するとtrueが返ってきます。

このように、比較演算子を直感的に扱うことが出来ることが、プリミティブ型の大きなメリットとなります。

5:nullを許容しない

Javaでプログラミングしていると、NullPointerExceptionに遭遇します。これはオブジェクトの参照先が未定義であり、ポインタの指し示す先がnullとなった時に発生します。

このエラーは非常に追いかけることが難しく、多くのプログラマを悩ませます。しかし、プリミティブ型では初期値が決まっておりnullは渡されず、またそもそもnullを代入出来ないのでこのようなエラーが発生し得ません。

これはバグを少なく、またトレーサビリティを向上させることができる、非常に大きなメリットとなります。

Javaのプリミティブ型について理解して転職に活かそう


今回はJavaの変数の型である、プリミティブ型の概要と特徴、使用した際のメリットについてまとめました。他言語との比較や、各型の概要をまとめ、初学者が混乱しやすい参照型、ラッパークラスとの比較を行いました。

このように、プリミティブ型は正しく扱えばバグを少なくし、ソフトウェアのパフォーマンスを向上させることも出来ます。

プリミティブ型を活用して、品質の高いソースコードを書けるようになりましょう。

インフラエンジニア専門の転職サイト「FEnetインフラ」

FEnetインフラはサービス開始から10年以上『エンジニアの生涯価値の向上』をミッションに掲げ、多くのエンジニアの就業を支援してきました。

転職をお考えの方は気軽にご登録・ご相談ください。