有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

注入泛型类型为@InjectGuice的类时发生java错误

我正在尝试使用带有@injectannotation的Guice将泛型类型的类(比如ClassA)注入另一个类(比如ClassB)。正在注入的类的代码如下所示:

public interface InterfaceA<T> {

}

public class ClassA<T> implements InterfaceA<T> {
    private final Class<T> data;
    private Dependency1 dependency1;

    @Inject
    public ClassA(Class<T> data, Dependency1 dependency1) {
        this.data = data;
        this.dependency1 = dependency1;
    }

}

B类的代码如下:

public class ClassB {
    private InterfaceA<Entity1> interfaceA;

    @Inject
    public ClassB(InterfaceA<Entity1> interfaceA) {
        this.interfaceA = interfaceA;
    }
}

模块类别如下所示:

public class MyModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(new TypeLiteral<InterfaceA<Entity1>>(){}).to(new TypeLiteral<InterfaceA<Entity1>>(){});
    }
}

但是,当应用程序启动时,会出现以下错误:

ERROR [2017-01-14 19:54:00,646] com.hubspot.dropwizard.guice.GuiceBundle: Exception occurred when creating Guice Injector - exiting
! com.google.inject.CreationException: Unable to create injector, see the following errors:
! 
! 1) Could not find a suitable constructor in java.lang.Class. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private.
!   at java.lang.Class.class(Class.java:119)

关于如何解决这一问题的任何意见都将非常有用。提前谢谢


共 (2) 个答案

  1. # 1 楼答案

    我终于找到了解决办法。这里,我不是在ClassA的构造函数中注入Class<T> data,而是注入TypeLiteral<T> literal,并使用它的getRawType()方法从TypeLiteral读取类类型

    ClassA的代码如下所示:

    public class ClassA<T> implements InterfaceA<T> {
        private final Class<? super T> data;
        private Dependency1 dependency1;
    
        @Inject
        public ClassA(TypeLiteral<T> literal, Dependency1 dependency1) {
            this.data = literal.getRawType();
            this.dependency1 = dependency1;
        }
    }
    

    其他类的其余代码与以前相同

  2. # 2 楼答案

    您不能以声明的方式执行此操作。您必须使用提供程序方法:

    public class MyModule extends AbstractModule {
      @Override protected void configure() {}
    
      @Provides InterfaceA<Entity1> provideInterfaceAEntity1(Dependency1 dep) {
        return new ClassA<Entity1>(Entity1.class, dep);
      }
    }
    

    这是唯一的方法,因为您无法在ClassA中自动注入Class<T>

    您需要在Module中为每个要与InterfaceA结合的Entity使用这样的方法