泛型通配符无法转换为Generictype

时间:2016-05-17 19:30:25

标签: java generics casting wildcard classcastexception

我遇到了一个我无法找到解决方案的问题。

我经常使用映射,其中键和值是具有匹配泛型的对象。对于每一对,泛型应该匹配。虽然条目之间的通用类型可能不同。 (为了清楚起见,我包括一个例子)。 这可以通过使用wildCard轻松完成。虽然因此,你不能将键或值与彼此结合使用。

考虑底部包含的示例。没有(简单)方法来修改地图以运行Cast异常。虽然我仍然无法使用我在useEntries()内尝试过的地图。所以我的问题是,有一个解决方法吗?提前谢谢!

public class GenericWildcardTest
{   
    static Map<GenericObject<?>, Function<?, ?>> map = new HashMap<>();

    public static <S> void put(GenericObject<S> genericObject, Function<S, S> function)
    {
        map.put(genericObject, function);
    }

    public static void useEntries()
    {
        for(Entry<GenericObject<?>, Function<?, ?>> currentEntry : map.entrySet())
            //The #apply(); part simply wont compile because of cast errors.
            currentEntry.getKey().set(currentEntry.getValue().apply(currentEntry.getKey().get()));
    }



    // Simple Object with generic.
    static class GenericObject<T>
    {
        private T object;

        public GenericObject(T object)
        {
            this.object = object;
        }

        public void set(T object)
        {
            this.object = object;
        }

        public T get()
        {
            return this.object;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

以下是如何通过投射来实现的:

@SuppressWarnings("unchecked")
public static <S> void useEntries() {
    for(Entry<GenericObject<?>, Function<?, ?>> currentEntry : map.entrySet()) {
        GenericObject<S> key = (GenericObject<S>)currentEntry.getKey();
        Function<S, S> value = (Function<S, S>)currentEntry.getValue();
        key.set(value.apply(key.get()));
    }
}

此答案假设您的地图确实包含Function<S, S>,而不是Function<GenericObject<S>, S>

答案 1 :(得分:0)

您可以按如下方式重写useEntries方法:

@SuppressWarnings("unchecked")
public static void useEntries() {
    for (Map.Entry<GenericObject<?>, Function<?, ?>> currentEntry : map.entrySet()) {
        GenericObject key = currentEntry.getKey();
        Function value = currentEntry.getValue();
        key.set(value.apply(key.get()));
    }
}

从方法中的GenericObjectFunction中删除泛型将允许您在纯Object个实例上进行调用。然后,您有责任确保正确打字。注释SuppressWarning将删除将以其他方式打印的编译警告。