Guice,绑定到枚举

Mac*_*iek 1 java enums guice

我很难弄清楚如何使用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不会选择任意的一个给你.

你可能想要做这三件事之一:

  1. 绑定Snack到特定类型Chocolate.

    bind(Snack.class).toInstance(Chocolate.DARK);
    
    Run Code Online (Sandbox Code Playgroud)
  2. 结合SnackChocolate,并Chocolate于特定类型的Chocolate.这就像上面所说的那样,但是现在你可以Chocolate直接询问并获得一个实例,而不仅仅是能够要求Snack.

    bind(Snack.class).to(Chocolate.class);
    bind(Chocolate.class).toInstance(Chocolate.DARK);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 允许开发人员注入一个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>,从而每次都得到一个新的实例...但是如果你希望在你的应用程序中使用它,那么共享一个不可变副本可能更有意义.