我正在尝试扩展在实体和实体管理器中使用泛型的库,所以我有以下内容:
public class MyEntity extends ParentEntity extends BaseEntity
和
public class MyEntityManager extends ParentEntityManager extends BaseEntityManager<ParentEntity, ParentEntityDao>
现在我的问题是,我正在使用库的另一个类来更新实体,而我需要调用的方法需要:
public <ENT extends BaseEntity> void update (Class<ENT> entityClass, BaseEntityManager<ENT> entityManager)
因此,当我尝试使用MyEntity
和MyEntityManager
调用该方法时,它会失败,因为我的EntityManager
从BaseEntityManager
扩展为ParentEntity
作为参数,不是MyEntity
,所以它们不匹配。
我想说解决这个问题的最简单方法是复制具有update方法的实用程序类并在我的项目中扩展它,但是我想让它通用所以我可以传递它使用任何子代的EntityManagers类ParentEntity
,但我已经尝试了一段时间,我找不到解决方案。
我尝试将方法签名更改为:
public <ENT extends BaseEntity> void update (Class<ENT> entityClass, BaseEntityManager<? extends ENT> entityManager)
但我仍然遇到编译器异常...
编辑:修改ParentEntityManager,BaseEntityManager或ParentEntity是不可能的,因为对这些类的依赖性太多
答案 0 :(得分:2)
由于它没有显示你可以轻松解决问题我会使用解决方法。您可以使用类型擦除。
update((Class) MyEntity.class, myEntityManager);
这将编译并发出警告。警告是有效的恕我直言,因为您的类结构不完全合乎逻辑;)如果您愿意,可以取消此警告。
我做的是;容器类返回它包含/管理的对象的类型。
class BaseEntityManager<E> {
private final Class<E> typeManaged;
public Class<E> typeManaged() { return typeManaged; }
}
// remove duplicate class parameter
public <ENT extends BaseEntity> void update (BaseEntityManager<ENT> entityManager)
管理员知道它管理的是什么类型,而update()方法可以通过调用typeManaged()
来询问它。这样可以避免必须提供匹配类型或检查此类型。
你遇到的问题是
MyEntityManager extends BaseEntityManager<ParentEntity>
你必须提供的类是ParentEntity.class而不是MyEntity.class。
看来真正的解决方案是你需要改变
MyEntityManager extends BaseEntityManager<MyEntity>
这将更合乎逻辑恕我直言并解决您的问题。
答案 1 :(得分:1)
您需要使用ParentEntity.class
和MyEntityManager
来调用更新方法,例如
update(ParentEntity.class, new MyEntityManager());
因为MyEntityManager
是BaseEntityManager<ParentEntity>
。
如果这不是您想要的(因为例如更新创建entityClass
的新对象并且您希望它们是MyEntity实例),您需要更改更新方法的签名并引入通配符:
public <ENT extends BaseEntity> void update (Class<? extends ENT> entityClass, BaseEntityManager<ENT> entityManager)
现在,您可以使用MyEntity.class
和MyEntityManager
来调用它。
答案 2 :(得分:0)
我认为如果你看看用Container替换Manager,那么问题就变得很明显了:MyEntityManager管理所有种类的超级ParentEntity类,而update方法则需要专门针对子类。
以下是否适合您?它编译,但lint抱怨
class BaseEntity {}
class BaseEntityManager<ENT extends BaseEntity> {}
class ParentEntity extends BaseEntity {}
class ParentEntityManager extends BaseEntityManager<ParentEntity> {}
class MyEntityManager extends ParentEntityManager { public void update(ParentEntity e) {}}
class MyEntity extends ParentEntity {}
class XEntityManager<ENT extends ParentEntity> extends BaseEntityManager<ENT>
{
MyEntityManager _delegate;
XEntityManager(MyEntityManager m)
{
_delegate = m;
}
public void update(ENT e)
{
_delegate.update(e);
}
}
class Foo {
public <ENT extends BaseEntity> void update (Class<ENT> entityClass, BaseEntityManager<ENT> entityManager) {}
void bar(MyEntity e, MyEntityManager m)
{
update(MyEntity.class, new XEntityManager(m));
}
}