roy*_*oyB 2 java generics bounded-wildcard
我有一个BaseDao接口,使用hibernate将数据持久化到mysql
public interface BaseDao<T extends Serializable> {
public void saveAll(Collection<T> objects) throws PersistenceException;
}
Run Code Online (Sandbox Code Playgroud)
我有一个实体类hirechy,他们的基类是BaseActivity(所有扩展可序列化)其中之一:
public class Activity1 extends BaseACtivity{...}
Run Code Online (Sandbox Code Playgroud)
在某些班级我宣布ActivityDao:
protected abstract ActivityDao<Activity1> createActivityDao1();
Run Code Online (Sandbox Code Playgroud)
和方法:
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) {
Run Code Online (Sandbox Code Playgroud)
at activityDao.saveAll(data)我得到一个编译时异常:
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
Run Code Online (Sandbox Code Playgroud)
BaseActivity:
public abstract class BaseActivity implements Serializable, Comparable<BaseActivity> {
Run Code Online (Sandbox Code Playgroud)
请帮助谢谢!
罗伊
更新:
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) {
Run Code Online (Sandbox Code Playgroud)
使用具有相同边界的两个有界通配符并不意味着它们是相同的类型.在这种情况下,实际类型参数ActivityDao<? extends BaseActivity>可能与出现的参数不同Collection<? extends BaseActivity>.所以,该saveAll()方法不起作用.
为了进一步详细说明,编译器使用唯一的占位符替换每个通配符出现,该占位符只是捕获该通配符.这意味着,Collection<?>变得Collection<CAP#1 of ?>同样Collection<? extends T>变Collection<CAP#1 of ? extends T>.如果Collection<?>再次遇到a,则将替换为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) {
}
}
Run Code Online (Sandbox Code Playgroud)
其中CAP#1和CAP#2是编译器的不同类型参数.当然,该saveAll方法的签名变为如下:
public void saveAll(Collection<CAP#1-of-? extends BaseActivity> objects) throws PersistenceException;
Run Code Online (Sandbox Code Playgroud)
并且因为Collection<T1>与Collection<T2>两个不同类型的参数不同,所以方法调用失败.
您可以使用泛型方法来解决此问题:
private <T extends BaseActivity> void persistData(ActivityDao<T> activityDao, Collection<T> data){
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
777 次 |
| 最近记录: |