Обратите внимание: Я провел целый день, чтобы убедиться, что это не дубликат.Большинство решений, которые я видел, основаны на вызове 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);
}
}
СейчасЯ хочу, чтобы возможность выводить универсальные типы любых экземпляров этих классов.Я пытаюсь добиться этого методом inferTypes
в Main.java
следующим образом:
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
Я не могу понять, как получить конкретные классы для второго случая.Любая помощь будет высоко ценится.