扩展方法参数中的泛型

时间:2011-09-05 08:56:30

标签: java generics

我正在尝试扩展在实体和实体管理器中使用泛型的库,所以我有以下内容:

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)

因此,当我尝试使用MyEntityMyEntityManager调用该方法时,它会失败,因为我的EntityManagerBaseEntityManager扩展为ParentEntity作为参数,不是MyEntity,所以它们不匹配。

我想说解决这个问题的最简单方法是复制具有update方法的实用程序类并在我的项目中扩展它,但是我想让它通用所以我可以传递它使用任何子代的EntityManagers类ParentEntity,但我已经尝试了一段时间,我找不到解决方案。

我尝试将方法签名更改为:

public <ENT extends BaseEntity> void update (Class<ENT> entityClass, BaseEntityManager<? extends ENT> entityManager)

但我仍然遇到编译器异常...

编辑:修改ParentEntityManager,BaseEntityManager或ParentEntity是不可能的,因为对这些类的依赖性太多

3 个答案:

答案 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.classMyEntityManager来调用更新方法,例如

update(ParentEntity.class, new MyEntityManager());

因为MyEntityManagerBaseEntityManager<ParentEntity>

如果这不是您想要的(因为例如更新创建entityClass的新对象并且您希望它们是MyEntity实例),您需要更改更新方法的签名并引入通配符:

public <ENT extends BaseEntity> void update (Class<? extends ENT> entityClass, BaseEntityManager<ENT> entityManager)

现在,您可以使用MyEntity.classMyEntityManager来调用它。

答案 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));
    }

}