我有一个抽象类,它采用泛型,在这个类中有一些方法。
我的问题是我不能使用通用的E inside方法。
public abstract class AbstractRepository<E> implements Repository<E> {
final Class<E> typeParameterClass;
public AbstractRepository(Class<E> typeParameterClass) {
this.typeParameterClass = typeParameterClass;
}
...
@Override
public E findById(Integer id) {
try {
this.entityManager.find(typeParameterClass, id);
} catch (IllegalArgumentException error) {
error.printStackTrace();
} catch (PersistenceException error) {
error.printStackTrace();
}
return null;
}
我尝试使用通用E作为&#39; find()&#39;的参数。如下所示,但我得到一个错误,表示E未定义。
@Override
public E findById(Integer id) {
try {
this.entityManager.find(E, id);
} catch (IllegalArgumentException error) {
error.printStackTrace();
} catch (PersistenceException error) {
error.printStackTrace();
}
return null;
}
要解决这个问题,我使用typeParameterClass。
typeParameterClass是一个扩展AbstractRepository的每个其他类必须传递的参数,这个参数是类本身,但它似乎不正确,因为我已经有了泛型类。
现在的方式示例:
@Repository
public class UserRepository extends AbstractRepository<User> {
public UserRepository(){
super(User.class);
}
...
}
那么,有没有办法在方法中使用泛型E?
存储库是一个也采用通用E的接口。
我在Spring中使用Hibernate。
答案 0 :(得分:0)
Java在运行时不存在泛型类型信息,因此无法确定用于具体实例的类型参数。
因此,处理此问题的唯一方法是通过Class
参数,因为这些参数设计为在运行时携带类型信息,并具有自引用泛型参数,这就是为什么你可以通过将其声明为E
,确保使用的类型属于您的类型Class<E>
。同样,所有泛型类型参数都只是编译器糖并在运行时被删除(因此它们只能确保没有人在您的实例中编写通过非E
类的代码)。
答案 1 :(得分:-1)
我在我的项目中使用了完全相同的方法,我在Gentyref的帮助下解决了这个问题,以获得更清晰的代码(maven,googlecode):
import static com.googlecode.gentyref.GenericTypeReflector.getExactSuperType;
import static com.googlecode.gentyref.GenericTypeReflector.getTypeParameter;
public abstract class GenericRepository<T> {
protected GenericRepository() {
Type genericRepositoryType = getExactSuperType(getClass(), GenericRepository.class);
Type rawItemType = getTypeParameter(genericRepositoryType, GenericRepository.class.getTypeParameters()[0]);
//noinspection unchecked
this.modelType = (Class<T>) GenericTypeReflector.erase(rawItemType);
}
}
你可以避免使用gentyref - 它的实现非常简单,但用这种代码编写代码要容易得多。