在Java通用接口中推断类参数的类型

时间:2018-12-12 11:37:46

标签: java generics type-inference

请注意::我已经整整一整天确保不会重复。我见过的大多数解决方案都依赖于对WebSecurityConfigureAdapter后跟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); } } 的{​​{1}}方法来实现这一目标,如下所示:

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

我无法弄清楚如何为第二种情况获得具体的课程。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

对于GenericClass<K, V>,在类文件中没有确定类型的信息。这是由于类型擦除引起的。

您能做的最好的就是从Map的内容中推断类型。如果您需要记录类型,可以

public class GenericClass<K, V> implements MyInterface<K, V> {
    private final Map<K, V> myMap;
    private final Class<K> keyClass;
    private final Class<V> valueClass

    public GenericClass(Class<K> keyClass, Class<V> valueClass) {
        this.myMap = new HashMap<K, V>();
    }

    public Class<K> getKeyClass() { return keyClass; }
    public Class<V> getValueClass() { return valueClass; }

即您需要显式存储类型。