1

次のコードを検討してください。

/**
 * For a given interface, return a default implementation
 */
public class ImplementationFactory<T>
{
  public static void main(String[] args)
  {
    AddressBookUI ui = ImplementationFactory.getImpl(AddressBookUI.class);
  }

  public static <T extends BasicUI> T getImpl(Class<T> uiClass)
  {
    if (uiClass.equals(AddressBookUI.class))
    {
      /*
       * Compile error if cast is removed.
       * Casting to T leaves an unchecked cast warning.
       */
      return (T) new AddressBookFrame();
    }

    // a bunch more else-if checks would be here

    return null;
  }
}

// These are defined elsewhere:
interface BasicUI {}
interface AddressBookUI extends BasicUI {}
interface StockQuoteUI extends BasicUI {}

class AddressBookFrame implements AddressBookUI {}
class StockQuoteFrame implements StockQuoteUI {}

そもそもなぜ getImpl() のキャストが必要なのですか? これについてもっと良い方法はありますか?

また、getImpl() でチェーンされた if-else チェックの代わりに、次のように Map を作成してみました。

private static Map<Class<? extends BasicUI>, Class<? extends BasicUI>> map;

次に、マップの値に対して newInstance() を呼び出しますが、問題は次のとおりです。

  • まだキャストしなければならなかった
  • 間違った実装をマップに入れると、型の安全性がなくなります。

理想的には、マップは

  • キー = いくつかの BasicUI インターフェイス
  • 値 = そのキーの何らかのクラス実装

しかし、私はそれを行う方法がわかりませんでした。

編集: BasicUI の別の実装をコードに追加しました

4

1 に答える 1

1

AddressBookFrameコンパイル時に anが のインスタンスであることを確認する方法がないため、キャストが必要ですT

警告を回避するには、実行時に型を確認します。

return uiClass.cast(new AddressBookFrame());

このようにすると、マップの実装が機能し、タイプ セーフになります。

于 2013-03-26T19:09:56.547 に答える