【发布时间】:2021-03-11 08:57:25
【问题描述】:
假设您正在编写一个库,它将作用于传递给它的客户端类(即无法更改客户端代码)。
class ClientClass {
public GenericClientClass<AnotherClientClass> someField;
}
我想做的是通过反射实例化 someField 。比如:
class LibraryClass{
public instantiateAllFields(Object obj){
//iterate through all fields of obj.class, and instantiate them
}
}
客户端字段的唯一要求是存在不带参数的构造函数。 (例如 GenericClientClass() {} )
这样做的目的是创建一个高度自动化的测试库,目前用于我自己的目的。
我已经能够为几乎所有情况(数组、对象、基元、泛型数组等)实现上述内容;然而,这个特殊的案例让我很难过。
field.getType().newInstance() 不起作用,因为删除了泛型类型参数。
field.getGenericType() 不起作用,因为它返回的是类型,而不是类。
如果这是一个已知的泛型类,我可以创建一个特殊情况来处理它。例如:
Class<?> genClass = ((Class<?>)((ParameterizedType)field.getGenericType()).getActualTypeArguments()[0]);
JArray jArray = new JArray(true,n,genClass);
field.set(object, jArray);
...我猜我可以为 ArrayList、HashMap 等东西做到这一点。
但是,我想介绍一般情况,并且能够实例化任何可以传递到库中的泛型类(使用单个参数和零参数构造函数)。
有什么想法吗?
请注意,泛型参数的类型已知。我可以通过 field.getGenericType() 得到它。
【问题讨论】:
-
没有“参数化类型的实例”这样的东西;或者,更确切地说,具有不同类型参数的参数化类型的实例之间没有区别。类型参数只是编译器用来强制类型正确性的东西。如果您在运行时实例化它,则编译器不在循环中。所以你只需要创建一个“原始”/“通配符”类型的实例,然后转换它。
标签: java generics reflection