简体   繁体   English

Java泛型 - 检索类型

[英]Java generics - retrieve type

public Interface Foo<T extends Colors>{...}

Is there a way to retrieve which T was given for an implementation of Foo? 有没有办法检索为Foo的实现提供哪个T?

For example, 例如,

public Class FooImpl implements Foo<Green>{..}

Would return Green. 将返回格林。

Contrary to other answers, you can obtain the type of a generic parameter. 与其他答案相反,您可以获取通用参数的类型。 For example, adding this to a method inside a generic class will obtain the first generic parameter of the class ( T in your case): 例如,将此添加到泛型类中的方法将获取该类的第一个泛型参数(在您的情况下为T ):

ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
type.getActualTypeArguments()[0]

I use this technique in a generic Hibernate DAO I wrote so I can obtain the actual class being persisted because it is needed by Hibernate. 我在我编写的通用Hibernate DAO中使用这种技术,因此我可以获得实际的类被持久化,因为它是Hibernate所需要的。 It works! 有用!

EDIT 编辑

Turns out for this case it is possible to get the generic information. 事实证明,这种情况可以获得通用信息。 Singleshot posted an answer which does just that. Singleshot发布了一个答案就是这么做的。 His should be the accepted answer. 他应该是公认的答案。 Re-qualifying mine. 重新认定我的。

In general though, there are many cases where you are unable to get type information you might expect to be there. 但总的来说,在很多情况下,您无法获得可能存在的类型信息。 Java uses a technique called type erasure which removes the types from the generic at compile time. Java使用一种称为类型擦除的技术,它在编译时从泛型中删除类型。 This prevents you from getting information about their actual binding at runtime in many scenarios. 这可以防止您在许多情况下在运行时获取有关其实际绑定的信息。

Nice FAQ on the subject: 这个主题的好常见问题:

There's. 有。 Look at [Javadoc for java.lang.Class#getGenericInterfaces()]( http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getGenericInterfaces()) . 查看[Javadoc for java.lang.Class#getGenericInterfaces()]( http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Class.html#getGenericInterfaces())

Like this: 像这样:

public class Test1 {

    interface GenericOne<T> {
    }

    public class Impl implements GenericOne<Long> {
    }

    public static void main(String[] argv) {
        Class c = (Class) ((ParameterizedType) Impl.class.getGenericInterfaces()[0]).getActualTypeArguments()[0];
        System.out.println(c);
    }
}

One way to do this is to explicitly pass in a Class object with the type. 一种方法是使用类型显式传入Class对象。 Something like the following: 类似于以下内容:

public class FooImpl<T extends Colors> {
  private Class<T> colorClass;
  public FooImpl(T colorClass) {
    this.colorClass = colorClass;
  }
  public Class<T> getColorClass() {
    return colorClass;
  }
}

Depends on what you mean exactly. 取决于你的意思。 Just T might be what you want, for example: Just T可能就是你想要的,例如:

public Interface Foo<T extends Colors>{ public T returnType() {...} ...}

[edit] Ok, apparently partially possible. [编辑]好的,显然部分可能。 Good explanation of how to do it, (including an improvement upon the method posted by SingleShot): http://www.artima.com/weblogs/viewpost.jsp?thread=208860 如何做的很好的解释,(包括对SingleShot发布的方法的改进): http//www.artima.com/weblogs/viewpost.jsp? thread = 208860

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM