我有一个通用的存储库类,如下所示:
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
// Many things that are working fine
@Override
public E getById(EId id) {
return entityManager.getReference(E.class, id); // <<< Error here!
}
}
方法getById()
应该返回给定Id
的某个实体实例。在许多其他情况下,这是非常微不足道的,但在这一情况下,因为编译器返回:
Illegal class literal for the type parameter E
请注意,我不想要将所需的类传递给该方法,因为我已经在类定义中执行了此操作。
此课程的用法可能是:
public class MyClassRepositoryHibernate
extends HibernateRepository<MyClass, Long> {
}
现在,此新存储库适用于MyClass
个实例,而Id
则使用Long
键入。
这可能在Java中吗?
答案 0 :(得分:2)
您必须将实际的类类型传递给HibernateRepository
的构造函数,并在整个方法中使用它。 JVM不知道运行时“E”是什么,因此您需要提供具体的类类型。
您可以通过在构造函数中使用Generic参数类型来确保不会错误地实例化对象,如下所示:
public class HibernateRepository<E extends Object, EId>
implements EntityRepository<E, EId> {
private Class<E> clazz;
public HibernateRepository(Class<E> clazz) {
this.clazz = clazz;
}
@Override
public E getById(EId id) {
return entityManager.getReference(clazz, id); // <<< Error here!
}
}
疼痛,但由于类型擦除是必要的。
答案 1 :(得分:0)
编译后将删除该类型,因此无法使用。这称为类型擦除。你必须在某处传递Class对象。