Developer

【はじめてのJava】ジェネリックスとラッパークラス【配列とArrayList編】
2021.08.31
Lv1

【はじめてのJava】ジェネリックスとラッパークラス【配列とArrayList編】

はじめてのJava

このシリーズでは、初めてJavaやプログラミングを勉強する方向けに、Javaによるプログラミングの基礎を説明していきます。
目標レベルは、Javaの資格試験の一つである「Oracle Certified Java Programmer, Silver」(通称Java Silver)に合格できる程度の知識の習得です。
はじめてJavaやプログラムに触れる方にもできるだけわかりやすい解説を心がけていきます。


目次


ArrayListを利用する際、

ArrayList<String> strArray = new ArrayList<String>();

のように記述していました。
この時、<String>という部分でArrayListに格納するデータ型を指定していますが、この<String>の部分をジェネリックスと呼びます。
ジェネリックスとは、<>を使ってデータ型を指定する仕組みのことです。
ジェネリックスを利用してデータ型を指定する際は、記述の仕方にいくつか注意が必要です。今記事ではArrayListでジェネリックスを使う際を例として解説していきます。
①ArrayListの変数を宣言する際、右辺と左辺で必ずデータ型を合わせること

ArrayList<String> strArray = new ArrayList<String>(); //OK
ArrayList<String> strArray = new ArrayList<Integer>(); //NG

②<>で指定したデータ型を格納すること(異なるデータ型を格納しようとするとコンパイルエラーとなる)

ArrayList<String> strArray = new ArrayList<String>();
strArray.add(“10”); //String型であるため格納できる。
strArray.add(10); //String型でないため格納できない。(コンパイルエラー)

③<>で指定できるデータ型はオブジェクト参照型のみで、基本データ型は指定できない。

ArrayList<String> strArray = new ArrayList<String>(); //OK
ArrayList<int> intArray = new ArrayList<int>(); //NG

ジェネリックスを使用する際は上記の3点に注意して記述しましょう。
また、ArrayListを利用する際にジェネリックスを使用しない記述も可能です。
例えば、

ArrayList strArray = new ArrayList();

のように記述することが出来ます。
ジェネリックスを使用せずに記述した場合、データを格納する際にデータ型のチェックが行われなくなります。
データ型のチェックを行わないため、コンパイル時には警告が出力されるようになります。
ただし、警告は出力されますが、コンパイル・実行ともに可能です。

ArrayList strArray = new ArrayList ();
strArray.add(“10”); //String型のデータを格納している。
strArray.add(10); //異なるデータ型だが、コンパイルエラーにはならない。

上記のようにジェネリックスを使用せずに記述すると、上記のように異なるデータ型をArrayListに格納するコードを記述してもコンパイルエラーになりません。
このように、ジェネリックスを使用しない場合、どのようなデータもArrayListに格納できるようになります。
その為、不正なデータを格納するコードを記述してしまった場合、プログラムを実行するまで不正なデータが格納されたことを検知できなくなってしまいます。

ジェネリックスを使用した場合は、データ型を宣言することで不正なデータを格納するコードを記述してしまった場合にコンパイルのタイミングで検知できるようになるという利点があります。

他にジェネリックスを使用する利点として、データを取り出す際に目的のデータ型へと変換を行うキャストという処理を行わなくて良いという利点もあります。(キャストについては別記事で詳しく解説します。)

ArrayList strArray = new ArrayList ();
strArray.add(“Apple”); //String型のデータを格納
String str1 = strArray.get(0); //コンパイルエラーとなる
String str2 = (String)strArray.get(0); //コンパイルエラーにならない。

上記のようにジェネリックスを使用しないで記述した場合、3行目のコードはコンパイルエラーとなります。String型のデータをArrayListに格納しましたが、「strArray.get(0)」で取り出したデータのデータ型がString型ではなくなってしまっているからです。
その為、取り出したデータをString型の変数に格納したい場合は、4行目のように記述する必要があります。
「(String)strArray.get(0)」と記述することで、取り出したデータをString型のデータに変換してからString型の変数に代入しています。この時の「(String)」と記述している部分がデータをString型のデータに変換している部分であり、キャストと呼ばれる処理に当たります。
このように、ジェネリクスを使用しないで記述した場合、格納したデータを取り出す際には目的のデータ型に変換するという処理を記述する必要が出てきます。
ジェネリックスを使用して記述した場合、ジェネリックスによってデータ型が指定されているので、データを取り出す際には自動でデータが変換されるようになります。その為、わざわざデータ型を変換する処理を記述する必要がなくなります。


ラッパークラスとは

ジェネリックスで指定できるのは、オブジェクト参照型のデータのみと上述しました。しかし、ArrayListに整数のような基本データ型のデータを格納したい場面は多くあります。
こういった場合に使用するのがラッパークラスです。
ラッパークラスは、基本データ型の値を参照型の値として扱うことを可能とします。各基本データ型にそれぞれ対応するラッパークラスが用意されています。
基本データ型とラッパークラスの組を表にまとめました。

基本データ型 ラッパークラス
int Integer
long Long
float Float
double Double
short Short
char Character
byte Byte
boolean Boolean

ほとんどの組が先頭の文字が大文字か小文字かという違いしかないので、ラッパークラスの名前を覚えるのは難しくないでしょう。
先頭の文字が大文字か小文字かで、扱いが大きく変わってしまうので注意しましょう。

ArrayList<Integer> intArray = new ArrayList<Integer>();
Integer i = 100;
intArray.add(i);

上記のようにラッパークラスとして記述することで、整数などの基本データ型のデータもArrayListに格納できるようになります。


ポイント

ジェネリックスを利用することで、不正なデータが格納されている記述を早期に発見できる。
ラッパークラスを利用することで、基本データ型のデータを参照型のデータとして扱うことが出来るようになる。