Java 解析异构映射

Java 解析异构映射,java,generics,heterogeneous,Java,Generics,Heterogeneous,我有一个JSON格式的异构映射,我想解析它并将其转换为异构映射对象类HeterogeneousMap 为了解析映射,我使用一个对象来定义所有已知的键,映射可以具有类HeterogeneousMapStructure MapKey接口具有方法T parseValueJsonReader jsonReader来解析键的值 我遇到的问题是如何将解析后的值放入类型安全的异构映射对象中: public class HeterogeneousMap { public <T> void p

我有一个JSON格式的异构映射,我想解析它并将其转换为异构映射对象类HeterogeneousMap

为了解析映射,我使用一个对象来定义所有已知的键,映射可以具有类HeterogeneousMapStructure

MapKey接口具有方法T parseValueJsonReader jsonReader来解析键的值

我遇到的问题是如何将解析后的值放入类型安全的异构映射对象中:

public class HeterogeneousMap {
    public <T> void put(MapKey<T> mapKey, T value) {
        // Put key and value in map
    }
}

public interface MapKey<T> {
    T parseValue(JsonReader jsonReader) throws IOException;
}

public class HeterogeneousMapStructure {
    private final List<MapKey<?>> keyList;

    public HeterogeneousMap parseMap(JsonReader jsonReader) {
        HeterogeneousMap heterogeneousMap = new HeterogeneousMap();

        // ... find matching key
        MapKey<?> matchingMapKey = ...;
        /*
         * Compiling error:
         * The method put(TestClass.MapKey<T>, T) in the type TestClass.HeterogeneousMap 
         * is not applicable for the arguments (TestClass.MapKey<capture#1-of ?>, capture#2-of ?)
         */
        heterogeneousMap.put(matchingMapKey, matchingMapKey.parseValue(jsonReader));

        return heterogeneousMap;
    }
}
有办法解决这个问题吗?

有办法解决。 您可以为此创建一个单独的方法:

private static <T> void parseAndPut(HeterogeneousMap map, MapKey<T> key, JsonReader in) throws IOException {
    map.put(key, key.parseValue(in));
}
并在解析映射中调用此方法:

public class HeterogeneousMapStructure {
    private final List<MapKey<?>> keyList;

    public HeterogeneousMap parseMap(JsonReader jsonReader) {
        HeterogeneousMap heterogeneousMap = new HeterogeneousMap();

        // ... find matching key
        MapKey<?> matchingMapKey = ...;
        /*
         * Compiling error:
         * The method put(TestClass.MapKey<T>, T) in the type TestClass.HeterogeneousMap 
         * is not applicable for the arguments (TestClass.MapKey<capture#1-of ?>, capture#2-of ?)
         */
        parseAndPut(heterogeneousMap, matchingMapKey, jsonReader);

        return heterogeneousMap;
    }

    private static <T> void parseAndPut(HeterogeneousMap map, MapKey<T> key, JsonReader in) throws IOException {
        map.put(key, key.parseValue(in));
    }
}
这应该行得通,但我没有你所有的课程,所以我不能真正测试它们。如果他们出了什么问题,告诉我,我会设法解决

我是如何想出这个解决方案的 问题在于类型通配符,或者说存在类型(如果您能理解的话)。Java使用这些通配符非常愚蠢。编译器将任意两个通配符视为可能的不同类型,即使它可以推断它们是相同的类型或它们位于相同的类型层次结构中。在你的情况下,两个captureX?被认为不相关,因此引发编译错误

因为问题是由于编译器无法推断,所以我们明确地告诉它。如您所见,我提取了操作并将存在类型指定为类型变量T,这样编译器现在就可以看到类型匹配,问题就解决了