以下是我遇到的问题的示例:
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 绑定(bind)到 Foo 时:
bind(IFoo.class).to(Foo.class).in(Singleton.class);
看起来helperMethod()
是在注入(inject)aaa
之前被调用的,因为我看到aaa
为null
。但是,如果我不使用 Helper
类并将其所有代码直接内嵌在 Foo
中,guice 就不会遇到困难。
这两种方法有什么区别?为什么在我们知道从哪里获得 IFoo
的实现之前就调用了 helperMethod()
?我们可以将 Helper
与注入(inject)一起使用吗?
最佳答案
您确定不是从 Helper
的构造函数中调用 helperMethod
吗?您在发布的代码中省略了该部分,但它与您所看到的行为相匹配。
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 class)构造函数,就像您键入 super()
;这必然作为子类构造函数中的第一个语句发生。因此,这种情况甚至在设置像 aaa
这样的最终变量之前就会发生,因此 Foo 中的重写方法会将 aaa
视为 null。正如我的示例中所示,这并不是 Guice 特有的,但 Guice 注入(inject)可以像其他任何东西一样触发构造函数。
This StackOverflow answer对此问题进行了更彻底的讨论。
关于java - Guice:注入(inject)用于实现抽象方法的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19107493/