JPA和Hibernate有一些方法可以使用一些我不理解的泛化返回类型,例如,
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass)
AbstractEntityManagerImpl中的。我本来期望返回类型为TypedQuery<T>
。 <T>
之前的TypedQuery<T>
表示什么?
对我而言,这不是一个纯粹的理论问题。我有一些代码给我编译错误。
TypedQuery<LogEntity> query =
entityManager.createNamedQuery(
"LogEntity.findByContentionText",
LogEntity.class);
错误如下:
method createNamedQuery in interface javax.persistence.EntityManager cannot be applied to given types;
required: java.lang.String
found: java.lang.String,java.lang.Class<mypackage.LogEntity>
reason: actual and formal argument lists differ in length
这有点误导,因为EntityManager.createNamedQuery
超载了:
public Query createNamedQuery(String name);
和
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass);
错误是指第一个定义,而我正在尝试匹配第二个定义。我做错了什么?
答案 0 :(得分:3)
必须在某个时候声明泛型类/方法的参数类型。对于泛型类,您可以在类定义中声明它:
class X<T> {}
另一方面,对于不泛型的类中的泛型方法,您必须在方法声明本身中声明它:
class NotGeneric{
public <T> X<T> genericMethod(String s, Class<T> cls){}
}
最后,您的错误可能是由于一个不同的问题,例如,您可能有javax.persistence
1.x 或的jar文件,都是1.x 和 2.0。重载方法was added in 2.0。
答案 1 :(得分:2)
返回类型为TypedQuery<T>
。返回类型之前的<T>
表示该方法是泛型方法,具有一个名为T
的泛型类型。
这意味着方法的调用者通过传递Class实例来决定返回的TypedQuery的类型。如果传递Foo.class作为参数,该方法将返回TypedQuery<Foo>
。
其他通用方法不能将泛型类型作为参数,调用者可以通过使用来决定使用哪种类型,例如
Collections.<Foo>emptyList();
您的代码无法编译,因为您的类路径中有一个旧版本的JPA,其中方法createNamedQuery(String, Class)
不存在(有关此旧版本的文档,请参阅http://docs.oracle.com/javaee/5/api/javax/persistence/EntityManager.html版本)。