2014-04-06 106 views
2

我有一个BaseDao接口使用留存数据到MySQL冬眠爪哇通配符错误

public interface BaseDao<T extends Serializable> { 
    public void saveAll(Collection<T> objects) throws PersistenceException; 
} 

我有一个实体类hirechy其基类是BaseActivity(所有延伸序列)其中 之一:

public class Activity1 extends BaseACtivity{...} 
在某些类

我声明了ActivityDao:

protected abstract ActivityDao<Activity1> createActivityDao1(); 

的d方法:

private void persistData(ActivityDao<? extends BaseActivity> activityDao, Collection<? extends BaseActivity> data){ 
    EntityTransaction transaction = activityDao.getEntityManager().getTransaction(); 

    try { 
     transaction.begin(); 

     activityDao.saveAll(data); 
     transaction.commit(); 
    } 
    catch (HibernateException ex) { 

在activityDao.saveAll(数据)我得到一个编译时异常:

Error:(62, 24) java: method saveAll in interface com.matomy.persistence.dao.BaseDao<T> 
cannot be applied to given types; 
required: java.util.Collection<capture#1 of ? extends 
com.matomy.persistence.entity.activities.BaseActivity> 
found: java.util.Collection<capture#2 of ? extends com.matomy.persistence.entity.activities.BaseActivity> 
reason: actual argument java.util.Collection<capture#2 of ? extends  com.matomy.persistence.entity.activities.BaseActivity> 
cannot be converted to java.util.Collection<capture#1 of ? extends  com.matomy.persistence.entity.activities.BaseActivity> 
by method invocation conversion 

BaseActivity:

public abstract class BaseActivity implements Serializable, Comparable<BaseActivity> { 

请帮助 谢谢!

罗伊

UPDATE:

private <T extends BaseActivity> void persistData(ActivityDao<T> activityDao, Collection<T> col){ 
    EntityTransaction transaction = activityDao.getEntityManager().getTransaction(); 

    try { 
     transaction.begin(); 

     activityDao.saveAll(col); 
     transaction.commit(); 
    } 
    catch (HibernateException ex) { 
+0

是BaseActivity序列化? – assylias

+0

yes:公共抽象类BaseActivity实现了Serializable,Comparable { – royB

+0

那么,这将是单调乏味的。这是同样的问题。你必须找到一些方法来使这个类具有通用性。或者你需要一些肮脏的解决方法来完成这项工作。 –

回答

5

两个限定通配符使用相同的绑定的使用并不意味着他们是同一类型。在这种情况下,ActivityDao<? extends BaseActivity>的实际类型参数可能与Collection<? extends BaseActivity>的实际类型参数不同。所以,saveAll()方法不起作用。

为了进一步阐述,编译器用一个唯一的占位符替换每个通配符的出现,该占位符只是捕获的通配符。这意味着,Collection<?>变为Collection<CAP#1 of ?>,类似地Collection<? extends T>变成Collection<CAP#1 of ? extends T>。如果再遇到Collection<?>,它将被替换为Collection<CAP#2 of ?>

所以,你的方法声明有点类似:

private void persistData(ActivityDao<CAP#1-of-? extends BaseActivity> activityDao, Collection<CAP#2-of-? extends BaseActivity> data){ 
    EntityTransaction transaction = activityDao.getEntityManager().getTransaction(); 

    try { 
     transaction.begin(); 

     activityDao.saveAll(data); 
     transaction.commit(); 
    } 
    catch (HibernateException ex) { 
    } 
} 

其中CAP#1CAP#2是编译器的不同类型的参数。当然,saveAll这个方法的签名变成这样:

public void saveAll(Collection<CAP#1-of-? extends BaseActivity> objects) throws PersistenceException; 

而且由于Collection<T1>是不一样的Collection<T2>两个不同类型的参数,使方法调用失败。

您可以通过使用通用的方法,而不是解决此问题:

private <T extends BaseActivity> void persistData(ActivityDao<T> activityDao, Collection<T> data){ 
+0

非常感谢您的答案!情况就是这样。发布问题之前,我试图实现该方法作为模板方法,但然后问题是,我有2通配符领域,当他们传递给方法结果在相同的错误。我正在更新代码 – royB

+0

@royB不客气:) –