2017-06-09 19 views
1

は、次のコードを考えてみましょう:のJavaジェネリック型パラメータ

public abstract class MyObject { 
} 

public interface Dao<T extends MyObject> { 
} 

public abstract class JsonDao<T extends MyObject> implements Dao<T> { 
} 

public abstract class SqliteDao<T extends MyObject> implements Dao<T> { 
} 

public interface DaoFactory<*????*> { 
    public *????* getDao(Class<? extends MyObject> objectClass); 
} 

今、私が好きなものをgetDaoがJsonDaoとSqliteDaoの両方をインスタンス化できるようにするためですが、MyObjectにを拡張するクラスでパラメータ化、このような基本的なもの:

public interface DaoFactory<T<? extends MyObject> extends Dao<? extends MyObject>> { 
    public <U extends MyObject> T<U> getDao(Class<U> objectClass); 
} 

同様のことも可能ですか、タイプ消去はできませんか?

+1

これは本当に型消去の問題ではありません。 Javaには、 'T 'のような構文構造のための機能がありません。 – Radiodef

+0

'interface DaoFactory >'? –

+0

@Jorn Vernee MyObjectを拡張する複数のクラスに対して、Daosをインスタンス化する必要があるため、できません。 –

答えて

1

あなたはDaoFactoryを宣言することができます:

public interface DaoFactory<D extends Dao<? extends MyObject>> { 

    <T extends MyObject> D getDao(Class<T> type); 
} 

その後、JsonDaoFactoryを実装することができ、次のように:

public class JsonDaoFactory implements DaoFactory<JsonDao<? extends MyObject>> { 

    private final Map<Class<? extends MyObject>, JsonDao<? extends MyObject>> daos = 
      new HashMap<>(); 

    public JsonDaoFactory() { 
     daos.put(Contact.class, new JsonContactDao()); 
     daos.put(Customer.class, new JsonCustomerDao()); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <T extends MyObject> JsonDao<T> getDao(Class<T> type) { 
     return (JsonDao<T>) daos.get(type); 
    } 
} 

私はMyObject試合のすべての子孫を作るためにMapを使用しました対応するJsonDao(ここではContactCustomerを使用しました)とJsonContactDaoおよびJsonCustomerDao)。私は明示的にコンストラクタ内のマップを塗っているので、チェックされていないキャスト警告を抑制したので、私はClassCastExceptionがないと確信しています。

は完全を期すため、ここではSqliteDaoFactoryのためのコードです:両方の工場のための

public class SqliteDaoFactory implements DaoFactory<SqliteDao<? extends MyObject>> { 

    private final Map<Class<? extends MyObject>, SqliteDao<? extends MyObject>> daos = 
      new HashMap<>(); 

    public SqliteDaoFactory() { 
     daos.put(Contact.class, new SqliteContactDao()); 
     daos.put(Customer.class, new SqliteCustomerDao()); 
    } 

    @Override 
    @SuppressWarnings("unchecked") 
    public <T extends MyObject> SqliteDao<T> getDao(Class<T> type) { 
     return (SqliteDao<T>) daos.get(type); 
    } 
} 

コードがほとんど重複しているが、私はこれを解決する方法を見つけることができませんでした。ここで

は、これらの工場を使用する方法は次のとおりです。

JsonDaoFactory jsonDaoFactory = new JsonDaoFactory(); 
JsonDao<Contact> contactJsonDao = jsonDaoFactory.getDao(Contact.class); 
JsonDao<Customer> customerJsonDao = jsonDaoFactory.getDao(Customer.class); 

SqliteDaoFactory sqliteDaoFactory = new SqliteDaoFactory(); 
SqliteDao<Contact> contactSqliteDao = sqliteDaoFactory.getDao(Contact.class); 
SqliteDao<Customer> customerSqliteDao = sqliteDaoFactory.getDao(Customer.class); 
+0

ええ、私はクラス階層の断片だけを投稿しましたが、私はDaoFactoryを実装する具体的なクラスでさらに一般性を使用しています。 –

+0

はい私はあなたが以下の@Aarjavのようなものだと思う、明日それを試してみよう: –

+0

あなたのコードはうまくいきますが、私はまだインスタンス化に執着しています。 JsonDao、すなわち:JsonContactDao(コンタクトはMyObjectを拡張し、JsonContactDaoはJsonDaoを拡張する)。私はgetDaoでJsonContactDaoをインスタンス化する方法を見つけることができません。 –

1

あなたのニーズに合っていますか?次のように

public interface DaoFactory<O extends MyObject, D extends Dao<O>> extends Dao<O> { 
    public D getDao(Class<O> objectClass); 
    //or for any subclass 
    public <RO extends O, RD extends D<RO>> RD getSubDao(Class<RO> objectSubclass); 

    //or maybe this 
    public <RO extends O> Dao<RO> getSimpleSubDao(Class<RO> objectSubclass); 
} 
+0

有望なサウンド!私はこれをテストしますtommorow私はあなたに知らせる! –

関連する問題