Java 使用反射获取字段的泛型类型

Java 使用反射获取字段的泛型类型,java,generics,reflection,java-8,Java,Generics,Reflection,Java 8,有没有一种方法可以在Java中获取字段的泛型类型 我有以下对象变量: protected ScheduleView<WantedClass> scheduleLine1; protected ScheduleView<SomeOtherClass> scheduleLine2; 问题是我还想在if语句中检查泛型类型是否为WantedClass。我还尝试了使用方法getGenericType(),但似乎这是不可能的: field.getGenericType() == S

有没有一种方法可以在Java中获取字段的泛型类型

我有以下对象变量:

protected ScheduleView<WantedClass> scheduleLine1;
protected ScheduleView<SomeOtherClass> scheduleLine2;
问题是我还想在if语句中检查泛型类型是否为
WantedClass
。我还尝试了使用方法
getGenericType()
,但似乎这是不可能的:

field.getGenericType() == ScheduleView<WantedClass>.class
field.getGenericType()==ScheduleView.class

那么有没有办法获取字段的泛型类型呢?

您必须检查该字段是否为
参数化类型,然后检查
getActualTypeArguments
的内容,例如

    for (Field field : Ideone.class.getDeclaredFields()) {
        Type type = field.getGenericType();
        if (type instanceof ParameterizedType) {
            ParameterizedType ptype = (ParameterizedType) type;
            if (ptype.getRawType() == ScheduledView.class) {
                if (ptype.getActualTypeArguments().length == 1
                    && ptype.getActualTypeArguments()[0] == WantedClass.class) {
                  // Do whatever with the field.
                  System.out.println(field.getName());
                }
            }
        }
    }

使用流实现@Andy Turner的答案:

// For each declared field in the class...
Arrays.stream(Ideone.class.getDeclaredFields())
  // select fields...
  .filter(
    // that have a generic type...
    field -> Stream.of(field.getGenericType())
      // that is an instance of ParametrizedType...
      .filter(ParameterizedType.class::isInstance)
      .map(ParameterizedType.class::cast)
      // whose raw type is ScheduledView...
      .filter(ptype -> ptype.getRawType().equals(ScheduledView.class))
      // and whose actual type arguments...
      .map(ParameterizedType::getActualTypeArguments)
      .flatMap(Arrays::stream)
      // include WantedClass...
      .anyMatch(WantedClass.class::equals)
  )
  // then get their names...
  .map(Field::getName)
  // and print them.
  .forEach(System.out::println)
;

不。这些在编译时被删除。您无法检索该类型。@f1sh您确定吗?这些不是类型变量(我猜)。@f1sh如果所有泛型类型都在编译时被删除,为什么
System.out.println(field.getGenericType())打印
控件。ScheduleView
?我错了,你是对的。@霍尔格流的使用现在被夸大了。@霍尔格过滤函数的详细程度降低了。
// For each declared field in the class...
Arrays.stream(Ideone.class.getDeclaredFields())
  // select fields...
  .filter(
    // that have a generic type...
    field -> Stream.of(field.getGenericType())
      // that is an instance of ParametrizedType...
      .filter(ParameterizedType.class::isInstance)
      .map(ParameterizedType.class::cast)
      // whose raw type is ScheduledView...
      .filter(ptype -> ptype.getRawType().equals(ScheduledView.class))
      // and whose actual type arguments...
      .map(ParameterizedType::getActualTypeArguments)
      .flatMap(Arrays::stream)
      // include WantedClass...
      .anyMatch(WantedClass.class::equals)
  )
  // then get their names...
  .map(Field::getName)
  // and print them.
  .forEach(System.out::println)
;