目次へ

2005.10.31 株式会社四次元データ CTO 畠中晃弘

1.3. 型引数

もう少し型引数について詳しく説明します。 型引数はクラス宣言・インタフェース宣言で、クラス名・インタフェース名に続いて指定します。 (正確にはクラス宣言・インタフェース宣言に登場しない、「ジェネリックなメソッド」というものも存在するのですが、後の章で解説します) 型引数は<>で囲み、その中に1つ以上の型変数を定義します。 java.util.Mapのように複数個指定する場合には、コンマ(,)で区切ります。

public interface Map<K, V>{
  ...

型変数の命名規則は変数の命名規則と同じですが、英大文字1字が推奨されています。

定義した型変数は、これまでの例に登場したimplements句やextends句、メソッドの引数、返り値だけでなく、インスタンス変数やメソッド内部で用いることもできます。

public class Value<V> {
    private V value=null;
    
    public Value(V value){
        this.value=value;
    }
    
    public V getValue(){
      return this.value;
    }
    
    public String toString(){
        return value.toString();
    }
}

この例ではインスタンス変数として、型引数で指定された型のオブジェクトvalueを指定しています。 またtoString()メソッド内で、valueのメソッドを呼び出しています。 valueの型はこのクラス作成時には一意に決まっていないのですが、必ずjava.lang.Objectのインスタンスにはなります。 従ってjava.lang.Objectのメソッドだけは、呼び出すことができます。 もし次のように型引数で指定できるクラスを限定した場合には、呼び出すメソッドも増えます。

import java.util.Date;

public class Term<S extends Date, E extends Date> {
    private S start=null;
    private E end=null;
    
    public Term(S start, E end){
        this.start=start;
        this.end=end;
    }
    
    public long calculateSpan(){
        return end.getTime()-start.getTime();
    }
}

extends句を用いて、型引数としてjava.util.Dateのサブクラスしか認めないようにしています。 この場合には、インスタンス変数startもendもjava.util.Dateのインスタンスになります。 従ってjava.util.Dateのメソッドも呼び出すことができます。 型引数で指定できるクラスの限定方法については、後の章で改めて説明します。

1.4. ジェネリクスなクラス・インタフェースの利用

ジェネリックなクラス・インタフェースを利用する場合には、変数宣言やnewでのインスタンス作成時に<>を用いて型引数を指定します。

Value<String> value=new Value<String>("test");

厳密には型引数はメソッド引数と違って必須ではありません。 したがって以下の3通りでもコンパイルエラーとはなりません。

Value value=new Value("test");
Value value=new Value<String>("test");
Value<String> value=new Value("test");

ただプログラム上の解りやすさの観点から言っても、ジェネリクスなクラス・インタフェースでは型引数を指定するのが適切です。

Value<String> value=new Value<String>("test");
とするようにしてください。

↑このページの先頭へ

こちらもチェック!

PR
  • XMLDB.jp