给定以下界面:
public interface GenericInterface<T> {
T getValue();
void setValue(T newVal);
}
以及以下 impl:
public class FixedImpl implements GenericInterface<String> {
String value;
public FixedImpl(String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
@Override
public void setValue(String newVal) {
value = newVal;
}
}
我希望能够通过询问来确定FixedImpl
,String.class
的值。GenericInterface.T
FixedImpl.class
我目前的想法:
GenericInterface
在其中找到一个返回 a的方法名称<T>
- 在这种情况下,有"getValue"
.- 遍历所有以
FixedImpl.class
相同名称声明的方法,并收集所有不同的返回类型。 - 最远的返回类型
Object
是我的值GenericInterface.T
。
但是这个过程有几个问题:
- 它仅适用于包含返回方法的泛型类型
<T>
。您不能使用 安全地执行相同的技巧setValue(T)
,因为在 Java 源代码中可以通过参数/arity 进行方法重载。它仅适用于T getValue()
因为返回值重载不是(除非我弄错了)。 - 它可能与 Java 8 默认方法或(仍然是通用的)可能抽象超类中的通用方法实现有奇怪的交互。
- 这有点笨拙。
谁能指出我更容易/更可靠的方式来获取相同的信息?我似乎找不到一个,但我想我会问 toobs 的高智商:)
注意:如果您想知道我为什么需要它,那是因为我想以编程方式构造具有类似硬编码类型参数的容器类的模拟,但使用 POJO 值而不是简单的字符串。
编辑:我最终制定了以下解决方案(在看到@stony-zhang's 之前):
public static <G> List<Class> getConcreteTypes(Class<? extends G> implClass, Class<G> genericClass) {
List<Class> concreteTypes = new ArrayList<Class>();
for (Type type : implClass.getGenericInterfaces()) {
if (!(type instanceof ParameterizedTypeImpl)) continue;
ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type;
if (parameterizedType.getRawType() != genericClass) continue;
for (Object arg : parameterizedType.getActualTypeArguments()) {
if (!(arg instanceof Class))
throw new IllegalArgumentException("Class " + implClass + " not concrete for generic type " + genericClass);
concreteTypes.add((Class) arg);
}
}
return concreteTypes;
}