给定以下界面:
public interface GenericInterface<T> {
T getValue();
void setValue(T newVal);
}
以及以下实现:
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
中查找方法名称返回<T>
- 在本例中,有"getValue"
. - 遍历
FixedImpl.class
中声明的所有方法具有相同的名称,并收集所有不同的返回类型。 - 距离
Object
最远的返回类型我的值是GenericInterface.T
.
但是这个过程存在一些问题:
- 它仅适用于包含返回
<T>
的方法的泛型类型。您不能使用setValue(T)
安全地执行相同的操作。 ,因为在 Java 源代码中可以通过参数/数量进行方法重载。它仅适用于T getValue()
因为返回值重载不是(除非我弄错了)。 - 它可能与 Java 8 默认方法或(仍然通用)可能抽象父类(super class)中的通用方法实现有奇怪的交互。
- 这有点困惑。
有人能给我指出一种更简单/更可靠的方法来获取相同的信息吗?我似乎找不到,但我想我应该问问那些高人一等的人:)
注意:如果您想知道为什么我需要这个,那是因为我想以编程方式构造具有类似硬编码类型参数的容器类的模拟,但 POJO 值而不是简单的字符串。
编辑:我最终找到了以下解决方案(在看到@stony-zhang 之前):
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;
}
最佳答案
可以通过以下方式获取T的类,在接口(interface)中添加一个方法getMessageClass(),并在FixedImpl中添加实现的方法,
@SuppressWarnings("rawtypes")
public Class getMessageClass() {
int index =0; //In the case, you only have a generic type, so index is 0 to get the first one.
Type genType = getClass().getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return Object.class;
}
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
if (index >= params.length || index < 0) {
throw new RuntimeException("Index outof bounds");
}
if (!(params[index] instanceof Class)) {
return Object.class;
}
return (Class) params[index];
}
在您的情况下,如果您有多个子类,要使用它,请创建一个抽象类来实现 GenericInterface 接口(interface),然后所有子类都从新的抽象类扩展,
public class abstract abstractImpl<T> implements implements GenericInterface<T> {
@SuppressWarnings("rawtypes")
@Override
public Class getMessageClass() {
...............
}
}
关于java - 是否有更简单的方法来检索子类实现中的硬编码类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16726167/