如何在方法中重用时获得类的泛型类型“T”

时间:2013-07-23 19:54:17

标签: java reflection sun-codemodel jcodemodel

我正在为Fluent API构建代码生成器。我想为每个现有(POJO)类创建一个新类。我没有我控制下的现有课程。我通过反射解析现有方法,如果遇到setter或“add”方法,我在Fluent-Wrapper类中创建了一个方法,所以我可以说child()。values(....)。get ()。

使用简单的参数可以正常工作。我花了一些时间来弄清楚如何处理ParameterizedTypes,但我现在可以管理它。我没有得到的是如何为泛型参数创建一个具体方法,该方法的类型没有在方法本身上定义,而是在包含类上。

我有这样的事情:

abstract class Parent<T> {
   void setValues(List<T> values) {...};
}

class Child extends Parent<String> {}

现在我尝试通过JCodeModel生成代码,并且需要解析参数“values”的类型。问题:我得到一个包含List和TypeVariable“T”的ParameterizedType。但我无法将“T”映射回String。但我无法弄清楚如何通过实施“儿童”获得具体的类型“T”。任何人吗?

澄清:我这样做,并且在“TypeVariable”案例中不需要“T”而是“String”

JType result = codeModel._ref(typeToClass.apply(type));
if (isParameterizedType(type)) {
  for (Type typeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
    if (typeArgument instanceof WildcardType) {
      result = narrow(result, codeModel.wildcard());
    } else if (typeArgument instanceof Class) {
      result = narrow(result, typeToClass.asJType(codeModel, typeArgument));
    } else if (typeArgument instanceof TypeVariable<?>) {
      TypeVariable<?> typeVariable = (TypeVariable<?>) typeArgument;
      // this is where I only get "T" but need "String"
      result = ((JClass) result).narrow(getTypeVariable(codeModel.parseType(typeVariable.getName()));
    }

  }
}

2 个答案:

答案 0 :(得分:0)

使用TypeTools

非常简单
Class<?> t = TypeResolver.resolveRawArgument(Parent.class, Child.class);

答案 1 :(得分:0)

试试这个......根据需要进行调整,添加错误检查等......

private Class<T> getType(int index) {
    final ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
    return (Class<T>) parameterizedType.getActualTypeArguments()[index];
}

用法:

Foo42<JFrame,String> foo = new Foo42<>();

if (getType(0).isAssignableFrom(JFrame.class)) {
    // is a JFrame
}

if (getType(1).isAssignableFrom(String.class)) {
    // is a String
}