我有一个DAO
对象,我通常用实体类名扩展,如下所示:
public class DAO<T> {
private final Class<T> clazz;
public DAO(Class<T> clazz {
this.clazz = clazz;
}
}
public class EntityDAO extends DAO<Entity> {
public EntityDAO() {
super(Entity.class);
}
}
但是,我有一些抽象的实体,我想创建一个抽象的DAO,稍后可以在具体的类中实现:
public class DAO<T> {
private final Class<T> clazz;
public DAO(Class<T> clazz {
this.clazz = clazz;
}
}
public abstract class AbstractEntityDAO extends DAO<T extends AbstractEntity> {
public AbstractEntityDAO () {
super(AbstractEntity.class);
}
}
public abstract class EntityDAO extends AbstractEntityDAO <Entity> {
public EntityDAO() {
super(Entity.class);
}
}
但这不起作用,因为AbstractEntityDAO
抱怨一个意外的界限,它无法解决T.是否可以这样做?如果是这样,它是如何写的?
这是使用Java 1.7
答案 0 :(得分:2)
将通用类型定义放在AbstractEntityDAO
:
public abstract class AbstractEntityDAO<T extends AbstractEntity> extends DAO<T> {
...
}
使用当前代码AbstractEntityDAO <Entity>
应该让编译器抱怨AbstractEntityDAO
没有通用参数。
此外,您的AbstractEntityDAO()
构造函数也需要接受Class
参数。但是,如果始终使用具有类型的类的实例,则根本不需要将该类作为参数传递。如果有T
中的具体定义,则使用反射类可以确定EntityDAO
的类型。内置的反射实用程序没有提供简单的方法来执行此操作,但幸运的是,您只需要一些额外的代码来提供一个,请查看此处:http://www.artima.com/weblogs/viewpost.jsp?thread=208860
这基本上也是我们正在做的事情。这是我们方法的粗略概述:
abstract class BaseDAO<T> {
Class<?> entityClass;
BaseDAO() {
//this is based on the link I posted above but basically uses the actual concrete class
//(subclass determined by getClass() ) to extract the generic types and
//since we only have one we get the first one from the returned list
entityClass = ReflectionHelper.getTypes(getClass(), BaseDAO.class).get(0);
}
public T getEntity(Object id) {
...
}
}
abstract class TranslatableDAO<T extends TranslatableEntity> extends BaseDAO<T> {
...
}
//Users are not translatable
class UserDAO extends BaseDAO<User> {
...
}
//Products are translatable, i.e. Product extends TranslatableEntity
class ProductDAO extends TranslatableDAO<Product> {
...
}