2011-12-29 63 views
2

如何在下面的Guice綁定代碼中抽象出Option類型,用通用參數代替Option如何編寫通用的Guice綁定函數?

ArrayList<Class<? extends Option>> options = 
new ArrayList<Class<? extends Option>>(); 
bindMultibinder(annotation, options); 

public Key<Set<Option>> bindMultibinder(
Named annotation, ArrayList<Class<? extends Option>> contents) { 
    Multibinder<Option> options = 
    Multibinder.newSetBinder(binder(), Option.class, annotation); 
    for (Class<? extends Option> option : contents) { 
     options.addBinding().to(option); 
    } 
    final Key<Set<Option>> multibinderKey = 
    Key.get(new TypeLiteral<Set<Option>>(){}, annotation); 
    return multibinderKey; 
} 
+0

「泛型相當於」絕不等同於你的第一個例子,因爲你沒有提供一種方法讓編譯器知道T的值是什麼。 – DwB 2011-12-29 19:34:59

+0

對不起@DwB,但我不認爲這是是這樣的。編譯器可以並且正確地推斷出T的正確類型。我推測它是從bindMultibinder方法中的類 superClass參數中這樣做的。也許你沒有看到這個參數? – 2011-12-29 19:52:50

回答

2

由於Stuart McCulloch在谷歌論壇回答:

^新TypeLiteral < ...>(){}匿名類招只有當 類型參數在編譯時已知的作品。

如果您需要建立泛型類型在運行時可以使用 com.google.inject.util.Types實用工具類,例如:

final Key<Set<T>> multibinderKey = 
    Key.get(Types.setOf(superClass), annotation); 

爲了得到這個建立正確,我修改它,如下所示:

final Key<?> multibinderKey = Key.get(Types.setOf(superClass), annotation); 

所以完整的通用方法是:

public <T> Key<?> bindMultibinder(
Named annotation, Class<T> superClass, ArrayList<Class<? extends T>> contents) { 
    Multibinder<T> options = 
    Multibinder.newSetBinder(binder(), superClass, annotation); 
    for (Class<? extends T> t : contents) { 
     options.addBinding().to(t); 
    } 
    final Key<?> multibinderKey = Key.get(Types.setOf(superClass), annotation); 
    return multibinderKey; 
} 
1

java.util.Set<T> cannot be used as a key; It is not fully specified.

對我說的是吉斯Key不使用泛型支持 - 你只能有一些完全指定(即沒有未綁定的類型參數)。

+0

感謝您解釋錯誤;這就說得通了。我敢打賭,我需要使用Guice TypeLiteral來實現這一點。如果我解決了問題,我會更新一個答案。 – 2011-12-29 19:50:29