这种双重泛型返回类型(public <t> TypedQuery <t>)表示什么?</t> </t>

时间:2014-05-06 18:13:51

标签: java hibernate generics jpa-2.0

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);

错误是指第一个定义,而我正在尝试匹配第二个定义。我做错了什么?

2 个答案:

答案 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版本)。