Revision 1 as of 2009-12-10 03:29:15

Clear message
Locked History Actions

guice/TypeParameter

型パラメータのある場合

型パラメータのあるインターフェースについてどのようにバインディング指定し、どのようにインスタンスを取得するか?

型パラメータを指定しない方法

型パラメータを無視してバインディング指定を行い、インスタンス注入を行う。

package test;
import com.google.inject.*;

public class TypeParameterZero {
  public interface Test<T> {}
  public static class TestA implements Test<String> {}  
  public static class Sample {
    @Inject Test one; // 型パラメータ無視
    void show() {
      System.out.println(one);
    }
  }  
  public static void main(String[]args) {
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override protected void configure() {
        bind(Test.class).to(TestA.class); // 型パラメータ無視
      }
    });
    Sample sample = injector.getInstance(Sample.class);
    sample.show();
  }
}

結果は以下になる。

test.TypeParameterZero$TestA@64dc11

もし、注入される側を以下のようにすると、

@Inject Test<String> one;

以下のエラーとなる。Guice側はバインディング時と注入時の型パラメータを把握しているのである。

Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for test.TypeParameterZero.test.TypeParameterZero$Test<java.lang.String> was bound.

この場合、バインディング指定を以下のようにすればよい。

  bind(new TypeLiteral<Test<String>>() {}).to(TestA.class);

もちろん以下のようには記述できない。TypeLiteralはこのような場合の代替として使う。

  bind(Test<String>.class).to(TestA.class);

逆に、バインディング時には上記のようにTypeLiteralを用いて型パラメータを指定し、注入側に生の型を使うと、

@Inject Test one;

やはりエラーとなる。

Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for test.TypeParameterZero$Test was bound.