2013-10-01 3 views
2

Вот пример вопроса я сталкивался:Guice: нагнетание параметр, используемый при реализации абстрактного метода

public interface IFoo { ... } 

public abstract class Helper implements IFoo { 
    public Helper() { ... } 

    protected abstract X helperMethod(); 
}  

public class Foo extends Helper { 
    private final String aaa; 

    @Inject 
    public Foo(String aaa) { this.aaa = aaa; } 

    @Override 
    X helperMethod() { doSomethingUsingWhatsInjected(aaa); } 
} 

Вопрос заключается в том, что, когда я связываю IFoo к Foo, как это:

bind(IFoo.class).to(Foo.class).in(Singleton.class); 

это выглядит как helperMethod() вызывается до того, как aaa было Введенный, поскольку я вижу, как aaanull. Но если я вместо этого не использую класс Helper и в строке всего его кода непосредственно в Foo, то он не будет бороться.

В чем разница между этими двумя подходами? Почему helperMethod() называется до того, как мы узнаем, откуда мы получаем реализацию IFoo? Можем ли мы использовать Helper вместе с инъекцией?

ответ

2

Вы уверены, что не звоните helperMethod с точностью до Helper? Вы пропустили эту часть из кода, который вы опубликовали, но это будет соответствовать поведению, которое вы видите.

public class Test { 
    interface IFoo { } 

    static abstract class Helper implements IFoo { 
    Helper() { helperMethod(); } 
    abstract void helperMethod(); 
    } 

    static class Foo extends Helper { 
    private final String aaa; 

    Foo(String aaa) { this.aaa = aaa; } 

    @Override 
    void helperMethod() { System.out.println(String.valueOf(aaa)); } 
    } 

    public static void main(String[] args) { 
    // Call helperMethod twice: 
    // once in the Helper.Helper(), once right here. 
    new Foo("expected").helperMethod(); 
    // output: 
    // null 
    // expected 
    } 
} 

Первое Foo делает неявно вызывается его конструктор суперкласса, как если бы вы ввели super(); это обязательно происходит как самый первый оператор в конструкторе подкласса. Следовательно, это происходит еще до того, как будут установлены конечные переменные, такие как aaa, поэтому ваш переопределенный метод в Foo видит aaa как null. Как и в моем примере, это не относится к Guice, но инъекция Guice может вызвать конструктор, как и все остальное.

This StackOverflow answer предлагает более обстоятельное обсуждение этой проблемы.

+0

Вы точно верны. Я проверил, и я * * вызываю 'helperMethod()' из конструктора 'Помощника'. Я ошибочно пропустил эту деталь, когда написал свой пример. Это отвечает на мой вопрос, спасибо! – apolune

Смежные вопросы