这是后续:my previous question
我的以下代码行不起作用:
IAccount account = (AccountModel) new AccountRepository().getByEmail(emailaddress);
...getByEmail(...)
的返回类型是 Model<Account>
,和AccountModel
延伸Model<Account>
.
但我得到了 java.lang.ClassCastException: models.Model cannot be cast to models.AccountModel
当我测试它时。我知道这是因为每个 AccountModel
是 Model<Account>
,但反之则不然。
有什么方法可以确保我可以解决这个问题(或解决它)。
public class AccountRepository extends Repository<Account> {
public AccountRepository() {
super(Account.class);
}
public Model<Account> getByEmail(String emailAddress) {
return this.getCustomHqlSingle("FROM Account a WHERE a.emailAddress = '" + emailAddress + "'");
}
}
public abstract class Repository<T> implements Serializable {
protected final Model<T> getCustomHqlSingle(String hql) {
List<Model<T>> t = this.getCustomHqlList(hql);
if (t != null && !t.isEmpty()) {
return t.get(0);
} else {
return null;
}
}
protected final List<Model<T>> getCustomHqlList(String hql) {
Session session = SESSION_FACTORY.openSession();
try {
session.beginTransaction();
List<T> entities = session.createQuery(hql).getResultList();
List<Model<T>> result = new ArrayList<>();
for (T t : entities) {
result.add(this.getByEntity(t));
}
return result;
} finally {
session.close();
}
}
<小时/>
对于将此问题标记为重复的人,让我改写我的问题中的以下句子:
I know this is because every
AccountModel
is aModel<Account>
, but not the other way around.
至
I know this is because every
Dog
is anAnimal
, but not the other way around.
最佳答案
您必须设计一种方法来转换 Model<Account>
到AccountModel
。从您的其他问题中获取代码,您可以为此添加一个构造函数到 AccountModel
类:
public class AccountModel extends Model<Account> implements IAccount {
private static final AccountRepository REPOSITORY = new AccountRepository();
public AccountModel(Account entity) {
super(entity, REPOSITORY);
}
public AccountModel(Model<Account> model) { // <---
super(model._entity, REPOSITORY);
}
// Method implementations...
}
然后更改您的AccountRepository
返回 AccountModel
的类来自getByEmail
:
public AccountModel getByEmail(String emailAddress) {
return new AccountModel(this.getCustomHqlSingle("FROM Account a WHERE a.emailAddress = '" + emailAddress + "'"));
}
它使用新的构造函数来转换 Model<Account>
到AccountModel
.
还有另一种选择。而不是打电话new Model<T>(...)
在Repository
,您可以让实现类实现一个抽象方法,该方法将返回所需的 Model
类型:
public abstract class Repository<T, R> implements Serializable
...
public Repository(Class<T> repositoryClass) {
if (!Repository._initiated)
setup();
this.cons = cons;
}
protected abstract R getModel(T entity, Repository<T> repo); // <--
然后在工厂方法中的某个地方:
public R getByFoo(...) {
...
T t = session.get(_repositoryClass, ...);
return getModel(t, this);
}
哪里AccountRepository
将返回一个新的 AccountModel
:
public class AccountRepository extends Repository<Account, AccountModel> {
public AccountRepository() {
super(Account.class);
}
@Override
protected AccountModel getModel(Account entity, Repository<Account> repo) {
return new AccountModel(entity);
}
}
关于java - 将泛型转换为子类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41462388/