Java中的通用存储库

Pap*_*ipo 2 java generics android dry

假设我有这个课程:

public class PhotoRepository  {
    private PhotoDao db;

    PhotoRepository(PhotoDao dao) {
        db = dao;
    }

    public void save(List<Photo> photos) { db.insertOrReplaceInTx(photos); }
    public List<Photo> all()  { return db.loadAll(); }
    public Photo get(Long id) { return db.load(id);  }
}
Run Code Online (Sandbox Code Playgroud)

由于我有更多种类的实体,而不仅仅是Photo,我希望有一个通用的存储库,我可以通过任何类型的Dao.

我已经尝试使用Class<? extends AbstractDao<?, ?>>构造函数的参数,但编译器说de dao方法无法解析.这些方面的东西:

public class Repository<T>  {
    private Class<? extends AbstractDao<T, ?>> db;

    Repository(Class<? extends AbstractDao<T, ?>> dao) {
        db = dao;
    }

    public void save(List<T> items) { db.insertOrReplaceInTx(items); }
    public List<T> all()  { return db.loadAll(); }
    public T get(Long id) { return db.load(id);  }
}
Run Code Online (Sandbox Code Playgroud)

我已尝试使用type参数,没有它,以及其他几种排列,没有运气.有没有办法在Java中这样做?

谢谢.

Kon*_*kov 5

你必须为类引入第二个类型参数Repository,它将代表dao,因为它Class<? extends AbstractDao<T, ?>>是不正确的.

我们称之为第二个类型参数D.它总是必须是一个子类AbstractDao,由你想要操作的对象类型参数化(即类型T)

public class Repository<T, D extends AbstractDao<T>>  {
    private D db;

    Repository(D dao) {
        db = dao;
    }

    public void save(List<T> items) { db.insertOrReplaceInTx(items); }
    public List<T> all()  { return db.loadAll(); }
    public T get(Long id) { return db.load(id);  }
}
Run Code Online (Sandbox Code Playgroud)

然后,您将能够实例化Repository:

Repository<Photo, PhotoDao> repo = new Repository<>(new PhotoDao());
Run Code Online (Sandbox Code Playgroud)

请注意,我假设PhotoDao被定义为:

class PhotoDao extends AbstractDao<Photo> { .. }
Run Code Online (Sandbox Code Playgroud)