我正在尝试从属性Map中绑定一堆类型,其中Key的类型是String,而map中的值类型是String,Boolean,Int,Long等,甚至是某种类型的对象。
这是在scala中,但同样适用于java
class GuiceFlagsModule(
flags: Map[String, Any])
extends AbstractModule
with Logging {
def configure() {
for ((flagName, flag) <- flags) {
debug("Binding flag: " + flagName + " = " + flag)
val key2 = Key.get(value.getClass, new FlagImpl(flagName))
binder.bind(key2).toInstance(value)
}
}
}
此处的最后一行无法编译
binder.bind(key2).toInstance(value)
如何才能编译它以便正确绑定泛型类型?
我刚刚在java中试过这个,它似乎在intellij中运行但是在javac编译器上失败了:(。
public void tryMe(Object someObj) {
Binder b = null;
Key k = Key.get(someObj.getClass(), new FlagImpl("name"));
b.bind(k).toInstance(someObj);
}
那么如何在java或scala中执行此操作?
我设法让它在java中工作
public static void bind(Binder binder, String flagName, Object value) {
Key<Object> key = Key.get((Class) value.getClass(), new FlagImpl(flagName));
binder.bind(key).toInstance(value);
}
我仍然没有在scala中使用它
感谢, 迪安
答案 0 :(得分:1)
您需要确保Key<T>
的类型参数与value
的类型匹配。
坏消息是:至少在一般情况下,我不知道有任何安全的方法。好消息是,可以通过未经检查的演员轻松完成。我不太清楚地知道Scala,但是在Java中我会这样写:
public static <T> void bind(Binder binder, String flagName, T value) {
@SuppressWarnings("unchecked")
Class<T> valueClass = (Class) value.getClass();
Key<T> key = Key.get(valueClass, new FlagImpl(flagName));
binder.bind(key).toInstance(value);
}
不幸的是,由于类型擦除(还有什么?),所以需要未经检查的强制转换,因为你会想到getClass()
doesn't return Class<T>
。
如果你知道value
的类型,那就更容易了:
public static <T> void bind(
Binder binder, String flagName, Class<T> valueClass, T value) {
Key<T> key = Key.get(valueClass, new FlagImpl(flagName));
binder.bind(key).toInstance(value);
}
但这当然只是将问题推迟给来电者。
答案 1 :(得分:0)
发布的解决方案对我不起作用:
public static void bind(Binder binder, String flagName, Object value) {
Key<Object> key = Key.get((Class) value.getClass(), new FlagImpl(flagName));
binder.bind(key).toInstance(value);
}
这会将所有内容绑定到java.lang.Class对象。但是,这有效:
Class impl = ...
Class intrf = ...
binder.bind(intrf).to(impl);