Java 泛型通配符无法强制转换为泛型类型

Java 泛型通配符无法强制转换为泛型类型,java,generics,casting,wildcard,classcastexception,Java,Generics,Casting,Wildcard,Classcastexception,我遇到了一个无法解决的问题 我经常使用映射,其中键和值是具有匹配generictypes的对象。对于每一对,泛型应该匹配。尽管条目之间的泛型可能不同。(为了清楚起见,我将举一个例子)。 这可以通过使用通配符轻松实现。尽管如此,您不能将键或值彼此组合使用 考虑下面的例子。没有(简单的)方法修改映射以运行强制转换异常。尽管我仍然无法像在useEntries()中尝试的那样使用映射。所以我的问题是,有没有解决办法?提前谢谢 public class GenericWildcardTest {

我遇到了一个无法解决的问题

我经常使用映射,其中键和值是具有匹配generictypes的对象。对于每一对,泛型应该匹配。尽管条目之间的泛型可能不同。(为了清楚起见,我将举一个例子)。 这可以通过使用通配符轻松实现。尽管如此,您不能将键或值彼此组合使用

考虑下面的例子。没有(简单的)方法修改映射以运行强制转换异常。尽管我仍然无法像在
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;
        }
    }
}
公共类GenericWildcardTest
{   
静态映射>映射=新HashMap();
公共静态无效放置(GenericObject GenericObject,函数)
{
map.put(genericObject,function);
}
公共静态void useEntries()
{
对于(条目>当前条目:map.entrySet())
//由于强制转换错误,#apply()部分根本无法编译。
currentEntry.getKey().set(currentEntry.getValue().apply(currentEntry.getKey().get());
}
//具有泛型的简单对象。
静态类GenericObject
{
私人T对象;
公共GenericObject(T对象)
{
this.object=对象;
}
公共无效集(T对象)
{
this.object=对象;
}
公共部门得不到
{
返回此.object;
}
}
}

您可以将
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()));
    }
}
@SuppressWarnings(“未选中”)
公共静态void useEntries(){
对于(Map.Entry>currentEntry:Map.entrySet()){
GenericObject key=currentEntry.getKey();
函数值=currentEntry.getValue();
key.set(value.apply(key.get());
}
}

从方法中的
泛型对象
函数
中删除泛型将允许您对纯
对象
实例进行调用。那你就有责任确保打字正确。注释
SuppressWarning
将删除否则将打印的编译警告。

您可以按如下方式重写
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()));
    }
}
@SuppressWarnings(“未选中”)
公共静态void useEntries(){
对于(Map.Entry>currentEntry:Map.entrySet()){
GenericObject key=currentEntry.getKey();
函数值=currentEntry.getValue();
key.set(value.apply(key.get());
}
}

从方法中的
泛型对象
函数
中删除泛型将允许您对纯
对象
实例进行调用。那你就有责任确保打字正确。注释
SuppressWarning
将删除编译警告,否则将打印这些警告。

以下是使用强制转换的方法:

@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()));
    }
}
@SuppressWarnings(“未选中”)
公共静态void useEntries(){
对于(条目>当前条目:map.entrySet()){
GenericObject键=(GenericObject)currentEntry.getKey();
函数值=(函数)currentEntry.getValue();
key.set(value.apply(key.get());
}
}

此答案假设您的地图确实包含
函数
,而不是
函数

以下是您如何使用强制转换来完成此操作:

@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()));
    }
}
@SuppressWarnings(“未选中”)
公共静态void useEntries(){
对于(条目>当前条目:map.entrySet()){
GenericObject键=(GenericObject)currentEntry.getKey();
函数值=(函数)currentEntry.getValue();
key.set(value.apply(key.get());
}
}

这个答案假设你的地图确实包含
函数
,而不是
函数

铸造是一个明显的解决办法。我对你的帖子和你的要求感到困惑。您正在使用泛型和通配符。我建议您完整地阅读本教程,它涵盖了泛型和通配符,并将阐明您的问题@shmosel你可能根本就没试着演这个?因为它不起作用。我甚至尝试用自己的泛型实现来创建一个私有方法。但这相当简单。generictype可以强制转换为通配符,但不能强制转换为Vicar。我认为您的意思是
apply(currentEntry.getKey().get())
。否则它将需要是
函数
currentEntry.getKey()
返回一个
generiObject
,这意味着编译器完全不知道
是什么。为了保证您没有做错,它只允许您设置它知道的合法内容,而这完全是徒劳的。或者,在不知道
是什么的情况下,您能否推断出
的等同或子类型是什么?为什么您的映射不是一个本身被键入为
的类中的(非静态)
HashMap
?那就行了。选角是一个明显的解决办法。我被你的帖子和你的要求弄糊涂了。您正在使用泛型和通配符。我建议您完整地阅读本教程,它涵盖了泛型和通配符,并将阐明您的问题@shmosel你可能根本就没试着演这个?因为它不起作用。我甚至尝试用自己的泛型实现来创建一个私有方法。但这相当简单。generictype可以强制转换为通配符,但不能强制转换为Vicar。我认为您的意思是
apply(currentEntry.getKey().get())
。否则它将需要是
函数
currentEntry.getKey()
返回一个
generiObject
,这意味着编译器完全不知道
是什么。为了保证您没有做错,它只允许您设置它知道的合法内容,而这完全是徒劳的。或者,在不知道
是什么的情况下,您能否推断出
的等同或子类型是什么?为什么是y