如何确定 Java 中泛型字段的类型?

我一直在尝试确定类中字段的类型。我已经看过所有的内省方法,但还没有完全弄清楚如何做到这一点。这将用于从java类生成xml / json。我在这里看了一些问题,但还没有找到我需要的东西。

例:

class Person {
    public final String name;
    public final List<Person> children;
}

当我编组此对象时,我需要知道该字段是 类型的对象列表,以便我可以正确地编组它。chidrenPerson

我试过

for (Field field : Person.class.getDeclaredFields()) {
    System.out.format("Type: %s%n", field.getType());
}

但这只会告诉我,它是一个,而不是a的ListListPerson

谢谢


答案 1

请参阅从 Java 教程跟踪中获取字段类型:反射 API

基本上,你需要做的是获取你的类的所有java.lang.reflect.Field,并在每个字段上调用Field#getType()(检查下面的编辑)。要获取所有对象字段,包括公共、受保护、包和私有访问字段,只需使用 Class.getDeclaredFields() 即可。像这样:

for (Field field : Person.class.getDeclaredFields()) {
    System.out.format("Type: %s%n", field.getType());
    System.out.format("GenericType: %s%n", field.getGenericType());
}

编辑:正如wowest在注释中指出的那样,您实际上需要调用Field#getGenericType(),检查返回的Type是否为a,然后相应地获取参数。使用 ParameterizedType#getRawType()ParameterizedType#getActualTypeArgument() 分别获取 的原始类型和类型参数的数组。下面的代码演示了这一点:ParameterizedTypeParameterizedType

for (Field field : Person.class.getDeclaredFields()) {
    System.out.print("Field: " + field.getName() + " - ");
    Type type = field.getGenericType();
    if (type instanceof ParameterizedType) {
        ParameterizedType pType = (ParameterizedType)type;
        System.out.print("Raw type: " + pType.getRawType() + " - ");
        System.out.println("Type args: " + pType.getActualTypeArguments()[0]);
    } else {
        System.out.println("Type: " + field.getType());
    }
}

并将输出:

Field: name - Type: class java.lang.String
Field: children - Raw type: interface java.util.List - Type args: class foo.Person

答案 2

这里有一个回答我问题的例子

class Person {
  public final String name;
  public final List<Person> children;  
}

//in main
Field[] fields = Person.class.getDeclaredFields();
for (Field field : fields) {
  Type type = field.getGenericType();
  System.out.println("field name: " + field.getName());
  if (type instanceof ParameterizedType) {
    ParameterizedType ptype = (ParameterizedType) type;
    ptype.getRawType();
    System.out.println("-raw type:" + ptype.getRawType());
    System.out.println("-type arg: " + ptype.getActualTypeArguments()[0]);
  } else {
    System.out.println("-field type: " + field.getType());
  }
}

此输出

field name: name
-field type: class java.lang.String
field name: children
-raw type:interface java.util.List
-type arg: class com.blah.Person