首页 > 解决方案 > 果汁注射器抛出空指针异常

问题描述

我正在尝试学习谷歌果汁。我有一个 InstallConfigurationModule 类,它具有创建 typeA 和 TypeB 对象所需的所有依赖项。并且,有一个类说类 Car ,如下所示,我正在尝试进行构造函数注入。当调用 run 方法时,在 system.out.println 行中出现空指针异常。我确定 ModuleA,ModuleB 自从在我的 InstallConfigurationModule 模块中创建 TypeA,TypeB 时,如果我说 Bind(TypeA.class) 或 Bind (TypeB.class),我收到谷歌果汁错误,“已配置到 typeA 或 typeB 的绑定”。

public class InstallConfigurationModule extends AbstractModule {

@Override
    protected void configure() {
        install(new ModuleA());
        install(new ModuleB());
    }
}
public class Car

{
  private Type A;
  private Type B;

@inject
  void SetCar(Type A, Type B)//not the constructor
 {
   this.A=A;
   this.B=B;
}

private void run()
{
  System.out.println(A.toString()) //throw null pointer exception
}

什么工作:

private void run()
    { 
     Injector injector = Guice.createInjector(new 
                         InstallConfigurationModule());

    TypeA typeA =injector.getInstance(TypeA.class);
      System.out.println(A.toString()) //works fine

    }

当我尝试不使用createInjector 时,为什么会得到NPE。任何帮助表示赞赏。

PS:对果汁很陌生。

标签: javadependency-injectionguice

解决方案


让我们假设我们有以下组件:

  • 类接口
public interface Type {}
  • 接口实现
public class TypeImpl implements Type {
    private String name;

    public TypeImpl(String name) {this.name = name;}

    public String getName() {return name;}

    @Override
    public String toString() {return name.toString();}
}
  • 一个配置模块
public class InstallConfigurationModule extends AbstractModule {
    @Override
    protected void configure() {
        super.configure();

        // new ModuleA()
        bind(Type.class).annotatedWith(Names.named("a")).toInstance((Type) new TypeImpl("a"));
        // new ModuleB()
        bind(Type.class).annotatedWith(Names.named("b")).toInstance((Type) new TypeImpl("b"));
    }
}

它不使用安装方法,但您可以使用它;configure 方法使用 Names.named API 将一个 TypeImpl 标记为“a”,另一个标记为“b”。

我们必须将 @Named 和 @Inject 注释放在 Car 类中

import com.google.inject.name.Named;

import javax.inject.Inject;

public class Car {
    private Type a;
    private Type b;

    @Inject
    public void setA(@Named("a") Type a) {
        this.a = a;
    }

    @Inject
    public void setB(@Named("b") Type b) {
        this.b = b;
    }

    public void methodIsCalled(){
        run();
    }

    private void run() {
        System.out.println(a.toString());
        System.out.println(b.toString());
    }
}

因此注入器将知道如何配置 Type 实例。

最后,在主类或配置类中,我们有以下语句

public class MainClass {
    public static void main(String[] args){
        Injector injector = Guice.createInjector(new InstallConfigurationModule());
        Car car = injector.getInstance(Car.class);

        // method that it calss the run method
        car.methodIsCalled();
    }
}

这是输出

a
b

推荐阅读