【发布时间】:2018-12-12 11:37:46
【问题描述】:
请注意:我花了一整天的时间确保这不是重复的。我见过的大多数解决方案都依赖于调用clazz.getGenericSuperclass(),然后调用getActualTypeArguments(),但这并不能解决我的问题,因为通用超类是java.lang.Object。
请继续阅读。
现在解决问题
我想实现一个提供通用接口的库。
public interface MyInterface<K, V> {
public V get(K key);
public void set(K key, V value);
}
然后用户可以在具体的类中实现它,例如:
import java.util.HashMap;
public class ConcreteClass implements MyInterface<String, Integer> {
private HashMap< String, Integer > myMap;
public ConcreteClass() {
this.myMap = new HashMap< >();
}
public Integer get(String key) {
return myMap.get(key);
}
public void set(String key, Integer value) {
myMap.put(key, value);
}
}
或者他们可能会实现另一个泛型类,例如:
import java.util.HashMap;
public class GenericClass<K, V> implements MyInterface<K, V> {
private HashMap<K, V> myMap;
public GenericClass() {
this.myMap = new HashMap<K, V>();
}
public V get(K key) {
return myMap.get(key);
}
public void set(K key, V value) {
myMap.put(key, value);
}
}
现在,我希望能够推断这些类的任何实例的泛型类型。我正在尝试在Main.java 中的inferTypes 方法中实现这一点,如下:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class Main {
private static <K, V> void inferTypes(MyInterface<K, V> mi) {
Class<?> clazz = mi.getClass();
// Should print whether "ConcreteClass" or "GenericClass"
System.out.println(clazz.getName());
Type[] ifaces = clazz.getGenericInterfaces();
for (Type iface : ifaces) {
// Should print "MyInterface<String, Integer>"
System.out.println(iface.toString());
Type[] types = ((ParameterizedType) iface).getActualTypeArguments();
for (Type type : types) {
// Should print "String" and then "Integer"
System.out.println(type.toString());
}
}
}
public static void main(String[] args) {
// Someone instantiates the class
ConcreteClass cc = new ConcreteClass();
// And I can successfully infers the type
Main.inferTypes(cc);
System.out.println("-------");
// Someone instantiates the generic class
GenericClass<String, Integer> gc = new GenericClass<>();
// And I can't infer the types this time
Main.inferTypes(gc);
}
}
它适用于ConcreteClass 的实例,但不适用于GenericClass 的实例。
ConcreteClass
MyInterface<java.lang.String, java.lang.Integer>
class java.lang.String
class java.lang.Integer
-------
GenericClass
MyInterface<K, V>
K
V
我不知道如何为第二种情况获取具体的类。任何帮助将不胜感激。
【问题讨论】:
-
@AnkurChrungoo,没有任何效果。此外,由于这些类将由库的用户实例化,因此我无法强制执行任何特定的实例化方式。
-
我假设你已经浏览过这个链接:stackoverflow.com/questions/53690045/…
-
@AnkurChrungoo,是的。正如我在顶部的注释中提到的那样。
getGenericSuperclass()方法不起作用,因为它返回类型为java.lang.Object的对象,我无法将其转换为ParameterizedType。给我一个编译时警告unchecked cast;和运行时ClassCastException。 -
是的,但实际上我的意思是使用库 github.com/leangen/… 。在这里可能会有所帮助。
-
我不知道这个。我去看看,谢谢但我不确定它在我的生产环境中是否可用。所以我可能不得不继续寻找使用标准 Java 库的解决方案。
标签: java generics type-inference