Categories: Java

【Java入門】ジェネリクス(総称型)と型推論

ジェネリクス(総称型)とは

ジェネリクスとは、型を指定することによってコレクションが扱える型を限定的にする機能です。
例えば、ArrayListを下記のように記述した場合、これはArrayListがString型しか扱えないことを指します。

Java

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

指定する型のことを型引数といい、ダイヤモンド演算子『<>』を用いて記述します。
なお、下記のように型変数を指定しない場合はObject型が渡されたものと推論されます。

Java

ArrayList list= new ArrayList();

ジェネリクスのメリット①:意図しない型による実行時エラーを防ぐ

例えば以下のようなコード。
このArrayListは型を指定していないため、どんな型の値でも扱うことができます。

Java

ArrayList list= new ArrayList<>();
list.add("abc");    //String
list.add(123);    //Integer
list.add(true);    //boolean

ジェネリクスを使わない場合、.get()メソッドで値を取得する際、String型が来るとわかっていてもキャストしなければならず、
またString型以外の値が来たときは実行時エラーになってしまいます。

Java

ArrayList list= new ArrayList();
list.add("abc");
list.add(123);
list.add(true);
String str1 = list.get(0);//この書き方ではコンパイルエラー。
String str2 = (String) list.get(0);//上のコードは←のようにキャストする必要がある。
String str3 = (String) list.get(1);//中身がint型なので実行するとClassCastExceptionが発生する。

下記のようにジェネリクスを利用することにより、コーディング段階で誤りに気付くことができます。

Java

ArrayList<String> list= new ArrayList<String>();
list.add("abc");
list.add(123);    //ここでコンパイルエラーが発生。
list.add(true);    //ここでコンパイルエラーが発生。

ジェネリクスのメリット②:クラスの型を汎用的にできる

Java

public class Generics<T> {
    private T element;

    public void setter(T element) {
        this.element = element;
    }

    public T getter() {
        return element;
    }
}

上記の<T>の部分にStringやIntegerを入れてインスタンス化することにより、
String型のGenericsクラスやInteger型のGenericsクラスを作ることが出来る。

Java

Generics<String> a = new Generics<String>();
a.setter("abc");
System.out.println(a.getter()); //abcが返却される。
Generics<Integer> b = new Generics<Integer>();
b.setter(123);
System.out.println(b.getter());    //123が返却される。

用語おさらい

用語 説明
<> ダイヤモンド演算子
<T> 型変数
型引数 Tの部分に代入するStringやIntegerのこと。

型推論とは

型推論とは、インスタンス生成時に、変数の型を決定する際、変数の宣言時と同じ型を使う機能のことです。
これにより今まで宣言時とインスタンス生成時の2箇所で型を記述していたのが1回で済みます。

Java

ArrayList<String> list= new ArrayList<String>();  //従来の書き方
ArrayList<String> list2= new ArrayList<>();   //これが型推論

以上で記事の解説はお終い!

もっとJavaやSpringを勉強したい方にはUdemyがオススメ!同僚に差をつけよう!

shiakisudev