guice绑定类型为未知类型但匹配类型

时间:2014-12-23 17:46:21

标签: java scala guice

我正在尝试从属性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中使用它

感谢, 迪安

2 个答案:

答案 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);