我很难弄清楚如何使用Guice将接口绑定到枚举.
public interface Snack {
public int caloriesCount();
}
public enum Chocolate implements Snack {
MILK(20),
DARK(5),
WHITE(10);
private int calCount;
private Chocolate(int calCount) {
this.calCount = calCount;
}
@Override
public int caloriesCount() {
return calCount;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试:
bind(Snack.class).to(Chocolate.class);
我明白了 No implementation for Chocolate was bound
我明白,我不应该尝试绑定到枚举,而应该绑定到枚举值的集合,但它无法实现如何实现.感谢任何提示.谢谢,Maciek
Jef*_*ica 13
绑定到这样的枚举类是不可能的,因为Guice无法创建自己的实例.在这里,默认行为是创建一个新的实例Chocolate,这没有多大意义 - 每个可能的枚举实例必须在枚举本身的编译时声明,并且Guice不会选择任意的一个给你.
你可能想要做这三件事之一:
绑定Snack到特定类型Chocolate.
bind(Snack.class).toInstance(Chocolate.DARK);
Run Code Online (Sandbox Code Playgroud)结合Snack到Chocolate,并Chocolate于特定类型的Chocolate.这就像上面所说的那样,但是现在你可以Chocolate直接询问并获得一个实例,而不仅仅是能够要求Snack.
bind(Snack.class).to(Chocolate.class);
bind(Chocolate.class).toInstance(Chocolate.DARK);
Run Code Online (Sandbox Code Playgroud)允许开发人员注入一个Set<Snack>,这恰好返回所有Chocolate实例.
// manual wildcard required so we don't get an ImmutableSet<Chocolate>
Set<Snack> setOfSnacks = ImmutableSet.<Snack>copyOf(Chocolate.values());
// bind a Set<Snack> specifically
bind(new TypeLiteral<Set<Snack>>() {}).toInstance(setOfSnacks);
Run Code Online (Sandbox Code Playgroud)
您可以使用任何Set实现,但由于所有toInstance绑定都是隐式单例,因此如果您使用GuavaImmutableSet或至少使用Guava,则可以降低一些修改风险Collections.unmodifiableSet.如果这接近你想要的,你可能有兴趣了解可选的Multibindings插件.
当然你也可以编写自己的Provider<Set<Snack>>或者一个方法@Provides Set<Snack>,从而每次都得到一个新的实例...但是如果你希望在你的应用程序中使用它,那么共享一个不可变副本可能更有意义.