Инжектор сока, выбрасывающий исключение нулевого указателя - PullRequest
0 голосов
/ 16 марта 2019

пытаюсь выучить гугл сок.У меня есть класс InstallConfigurationModule, у которого есть все зависимости, необходимые для создания объекта типа A и TypeB. И я получил класс скажем класс Car, как показано ниже, и пытаюсь выполнить инжекцию конструктора.Когда вызывается метод run, я получаю исключение нулевого указателя в строке system.out.println. Я точно знаю, что ModuleA, ModuleB имеет ссылку на создание TypeA, TypeB, поскольку в моем InstallConfigurationModulemodule, если я говорю Bind (TypeA.class) или Bind(TypeB.class), я получаю ошибку google juice, «привязка к типу A или типу B уже настроена».

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

    }

Почему я получаю NPE, когда пытаюсь обойтись без созданияInjector.Любая помощь приветствуется.

PS: очень новый для сока.

1 Ответ

1 голос
/ 17 марта 2019

Предположим, что у нас есть следующие компоненты:

  • интерфейс класса
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 использует API Names.name, чтобы пометить 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());
    }
}

Таким образом, инжектор будет знать, как настроить экземпляры типа.

Наконец, в основном классе или классе конфигурации у нас есть следующие операторы

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
...