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' かどうかを確認し、parse を呼び出すことはできますか?

また、メソッドでコンパイル時に IFoo<-->Foo 実装関係を強制しgetItem()、型キャストを削除する方法があるかどうか疑問に思っていました(T)か?

編集:私は概要を説明すると思いましIFooFoo

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


class Foo implements IFoo, IParsable
{
      ...
}

EDIT2:

このようなリファクタリングを考えただけで、コンパイル時のチェックではない唯一のものは、インターフェイスと実装の関係です。

  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

次のように、クラスのセットアップ時にすべてのマッピングを登録する必要があります (同じ型パラメーターで複数の境界をチェックできないため、見苦しくなります):

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 に答える
1

ここで具象クラスは IParsable を実装します。実行時のアサート チェックを削除し、コンパイル時のチェックを入れて、'IParsable' かどうかを確認し、parse を呼び出すことはできますか?

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 に答える