java - 解析 TypeVariable

标签 java reflection bytecode-manipulation

假设我有这些类(class):

class Container<T> {
  private List<T> list;
}

我有一个 Container 的实例,比如说

Container<?> instance = new Container<String>();

有没有办法在运行时找出 list 的实际类型参数?也就是说,它是 StringList,而不是 java 的 List。 lang.reflect.TypeVariable.

我一直在研究 Java 的反射(field.getGenericType())、各种库(Guava ReflectTypetoolsClassMate、甚至ASM 等)但是我想不通。

我无法控制 Container 类型,因此无法向其添加任何字段。

我意识到由于删除,这可能根本不可能,尽管如果可能的话,我不介意弄乱字节码。

编辑 我过度简化了我最初的问题。我有一条额外的信息可用;我也有这种:

class StringContainerContainer {
  private Container<String> container;
}

(还有更多类似的类型,用于不同的通用参数。)

在运行时,我得到了上面提到的 instance 对象。通过对我的代码库进行一些重构,我还可以访问 StringContainerContainer 类(或任何相关的 *ContainerContainer 类),我可以使用它来获取 java.lang.reflect.Field 用于容器

最佳答案

通过您的编辑,是的,您可以发现 String 是实际的类型参数:

Field field = StringContainerContainer.class.getDeclaredField("container");
ParameterizedType gt = (ParameterizedType) field.getGenericType();
Class<?> arg = (Class<?>) gt.getActualTypeArguments()[0];
System.out.println(arg);

我应该指出,这标识了 StringContainerContainercontainer 字段的类型参数。考虑到 Container 的编写方式,这也恰好是其 list 字段的类型参数,但不会直接检查该字段。

关于java - 解析 TypeVariable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34665941/

相关文章:

java - 消化 md5 抛出 UTF8 错误 - Java

java - 使用 javassist 通过字节码中的方法替换 java 运算符

java - 如何在Class.class中使用泛型

java - 在已编译的 Java 类中重写方法调用

java - Java 对象何时完全初始化?

java - 8x8 位乘法的最大范围

java - ServerSocket(端口)上的困惑

java - 使用三元运算符初始化数组

c# - 如何使用 ReflectionPermission 拒绝反射

没有限定名称的Java反射