型パラメータとは
ジェネリクスのデータ型を後で決めるために一時的に使用するパラメータ。
例
class Box<T> {
private T contents;
public void setContents(T contents) {
this.contents = contents;
}
public T getContents() {
return contents;
}
}
上記の「T
」となっている部分が型パラメータである。この部分は、実行時にどの型を使うかを指定することで、そのインスタンスが持つフィールドやメソッドの型パラメータが置き換わる。
この時、ジェネリクスを使用して型を記述する。
なお、型パラメータを受け取るクラスを扱うクラスに型パラメータを渡さなかった場合、Object
型の型パラメータが渡されたものとして解釈される。
ジェネリクスとは
ダイヤモンド演算子「<>
」で囲まれたデータ型をクラスやメソッドにつけることで、そのクラスやメソッドが扱うデータ型を実行時に決めることができる。
また、ジェネリクスを使用したクラスのことを「総称型」と呼ぶ。
ジェネリクスの性質
ジェネリクスは基本的には非変である。
非変とは、異なる型の間での型の関係が維持され、互換性がないことを意味する。
ジェネリクスを使用したクラスやインターフェースにおいて、異なる型引数が指定された場合、それらは別々の型として扱われる。
たとえ2つの異なるジェネリクス型が同じ基本クラスを継承していても、それらは直接的な型の関係を持たない。
例
public class Main {
public static void main(String[] args) {
Box<String> stringBox = new Box<>();
Box<Integer> integerBox = new Box<>();
// コンパイルエラー: stringBoxとintegerBoxは別々の型として扱われる
// stringBox = integerBox;
}
}
上記の例では、Box
クラスがジェネリクスで実装されている。Box<String>
とBox<Integer>
は異なる型として扱われ、互換性がない。
そのため、stringBox = integerBox;
のような代入はコンパイルエラーとなる。
ただし、ジェネリクスにはワイルドカードと呼ばれる特殊な機能も存在する。ワイルドカードを使用することで、ある程度の柔軟性を持たせることができる。