2

我有

public class  MyFactory()
{
   public static <T> T getItem(Element element, Class<T> clazz)
   {
         T item = null;
         if (clazz == IFoo.class)
         {
              item =  (T) new Foo();
         }
         else if (clazz == IBar.class)
         {
              item =  (T) new Bar();
         }
         ...

        assert item instanceof IParsable;
        (IParsable(foo)).parse(element)

       return item;
   }

}

然后我这样称呼它

IFoo parsedFoo = MyFactory.getItem(someElement, IFoo.class);

这里具体类实现IParsable。我是否能够删除运行时断言检查并进行编译时检查以查看是否“IParsable”并调用解析?

另外我想知道是否有办法在getItem()方法的编译时强制执行 IFoo<-->Foo 实现关系并删除类型转换(T)

IFoo编辑:我想我会给出一个大纲Foo

public interface IFoo
{
    String getFooName();
    int getFooId();
    ....
}


class Foo implements IFoo, IParsable
{
      ...
}

编辑2:

我只是想到了这样的重构,现在唯一不是编译时检查的是接口和实现之间的关系。

  public static <U extends IParsable, T> T getItem(Element element, Class<T> clazz)
   {
         U item = null;
         if (clazz == IFoo.class)
         {
              item =  (U) new Foo();
         }
         else if (clazz == IBar.class)
         {
              item =  (U) new Bar();
         }
         ...

       item.parse(element)

       return (T) item;
   }
4

3 回答 3

3

也许是这样的:

public static <T> T getItem(Element element, Class<T> clazz) {
    IParsable item = null;
    if (clazz == IFoo.class) {
        item = new Foo();
    } else if (clazz == IBar.class) {
        item = new Bar();
    }
    item.parse();
    return (T) item;
}

Foo这是IParsable在编译时检查的事实。另一个演员 (to (T)) 仍然是运行时练习 - 但在您的示例中也是如此。

于 2013-04-01T15:10:26.280 回答
1

这里的具体类实现了 IParsable 。我是否能够删除运行时断言检查并进行编译时检查以查看是否“IParsable”并调用解析?

From what I know - no, it's not possible. You will be passing object to this method at runtime, the compiler has no idea what objects will be passed. So compile time is not an option here. 

另外我想知道是否有办法在 getItem() 方法中强制 IFoo<-->Foo 在编译时实现关系并删除类型转换 (T) ?

Again, only at runtime with isAssignableFrom
于 2013-04-01T15:08:50.730 回答
1

您应该像这样在类设置时注册所有映射(这很丑陋,因为您不能使用相同的类型参数检查多个边界):

private static Map<Class<?>, Class<?>> MAPPINGS = ...;

static {
  registerMapping(IFoo.class, Foo.class, Foo.class);
  // ...
}

private static <IT, TT extends IT, TP extends IParseable> void registerMapping(Class<IT> ifaceClazz, Class<TT> implClazz, TP parseableClazz) {
  MAPPINGS.put(ifaceClazz, implClazz);
}

然后在getItem()您的 if 块中变成一个简单的地图查找。请注意,这不会摆脱(T)演员阵容,但您对此无能为力。

于 2013-04-01T15:13:51.137 回答