繁体   English   中英

错误:类型参数枚举不在类型变量 T 的范围内

[英]error: type argument Enum is not within bounds of type-variable T

我对这段代码有疑问。 当我想插入 Map EnumElement 消费者时,它无法编译并出现错误error: type argument Enum is not within bounds of type-variable T 问题是我无法更改 *Value 类。 有没有办法让它工作?

import java.util.*;
import java.util.function.*;

public class Main {
    public static void main(String[] args) {}
    
    private static final Map<Class<?>, Consumer<Element>> CONFIG_ELEMENTS = new HashMap<>();

    static {
        CONFIG_ELEMENTS.put(BooleanValue.class, element -> new BooleanElement((ConfigElement<Boolean, BooleanValue>) element));
        // CONFIG_ELEMENTS.put(EnumValue.class, element -> new EnumElement<>((ConfigElement<Enum, EnumValue<Enum>>) element)); // doesn't compile
    }
    
    
    private static class ConfigValue<T>{}
    
    private static class BooleanValue extends ConfigValue<Boolean> {}
    
    private static class EnumValue<T extends Enum<T>> extends ConfigValue<T> {}
    
    
    private static class Element{}
    
    private static class ConfigElement<S, T extends ConfigValue<S>> extends Element {}
    
    private static class BooleanElement extends ConfigElement<Boolean, BooleanValue> {
        BooleanElement(ConfigElement<Boolean, BooleanValue> value) {}
    }
    
    private static class EnumElement<T extends Enum<T>> extends ConfigElement<T, ConfigValue<T>> {
        EnumElement(ConfigElement<T, ConfigValue<T>> value) {}
    }
}

:我让您的示例

我在您的几个类中添加了一些骨架实现,以确认该解决方案可用:

…
static public void main( String ...args ){
        
    EnumValue< Foo > ev = new EnumValue< >( );
        
    ConfigElement< Foo, EnumValue< Foo > > ce = new ConfigElement< >( );
        
    EnumElement< Foo > ee = new EnumElement< >( ce );
        
    ee.setE( Foo.BAR );
        
    Foo bar = ee.getE( );
    
    out.println( bar );
    
    Consumer< Element > c = CONFIG_ELEMENTS.get( ev.getClass( ) );
    
    c.accept(ee);
}
…

如果您想检查它是否为您编译和运行,请单击上面链接中在线 IDE 项目顶部的绿色开始按钮。

首先,让我们弄清楚一些事情。 您的第一个CONFIG_ELEMENTS.put...相当于(只要确保您理解这一点)。

CONFIG_ELEMENTS.put(
        BooleanValue.class,
        element -> {
            new BooleanElement((ConfigElement<Boolean, BooleanValue>) element);
            return;
        }
);

现在你声明的CONFIG_ELEMENTS map 知道它持有的值是Element类型,即上面可以写成:

CONFIG_ELEMENTS.put(
        BooleanValue.class,
        (Element element) -> {
            new BooleanElement((ConfigElement<Boolean, BooleanValue>) element);
            return;
        }
);

这就是为什么使这项工作的唯一方法是转换该element的原因; 因为它是Element类型,但您的BooleanElementConfigElement作为输入。 这应该是显而易见的。


第二个CONFIG_ELEMENTS.put...解释必须从这个开始:

private static class EnumElement<T extends Enum<T>> extends ConfigElement<T, ConfigValue<T>> {

    EnumElement(ConfigElement<T, ? extends ConfigValue<T>> value) {

    }
}

注意? extends ConfigValue<T>> value ? extends ConfigValue<T>> value部分。 你需要它,因为generics 是不变的,所以为了能够传递扩展ConfigValue的东西,你需要正确声明参数类型。

解释的 rest 是我纯粹的有根据的猜测,因为我并不真正理解这里发生了什么(我有一些提示,这与使用原始类型有关,并且来自EnumElementT和来自EnumValueT是不同类型的变量)...

使这项工作的最简单方法,IMO,是改变这个:

private static class EnumValue<T extends Enum> extends ConfigValue<T> {}

使用原始Enum

编辑

这是评论中要求的完整示例:

public class DeleteMe {


    private static final Map<Class<?>, Consumer<Element>> CONFIG_ELEMENTS = new HashMap<>();

    static {
        CONFIG_ELEMENTS.put(BooleanValue.class, element -> new BooleanElement((ConfigElement<Boolean, BooleanValue>) element));
        CONFIG_ELEMENTS.put(EnumValue.class,
                            element -> new EnumElement<>((ConfigElement<Enum, EnumValue<Enum>>) element)); // doesn't compile
    }


    private static class BooleanValue extends ConfigValue<Boolean> {}

    private static class BooleanElement extends ConfigElement<Boolean, BooleanValue> {

        BooleanElement(ConfigElement<Boolean, BooleanValue> value) {}
    }

    private static class ConfigValue<T> {

    }

    private static class EnumValue<TT extends Enum> extends ConfigValue<TT> {}


    private static class Element {}

    private static class ConfigElement<S, T extends ConfigValue<S>> extends Element {}


    static class EnumElement<T extends Enum<T>> extends ConfigElement<T, ConfigValue<T>> {

        EnumElement(ConfigElement<T, ? extends ConfigValue<T>> value) {

        }

        private T e;
        
        public void setE(T e) { this.e = e; }

        public T getE() { return e; }
    }


    static public void main(String... args) {

        EnumValue<Foo> ev = new EnumValue<>();
        ConfigElement<Foo, EnumValue<Foo>> ce = new ConfigElement<>();
        EnumElement<Foo> ee = new EnumElement<>(ce);
        ee.setE(Foo.BAR);
        Foo bar = ee.getE();
        System.out.println(bar);
        Consumer<Element> c = CONFIG_ELEMENTS.get(ev.getClass());
        c.accept(ee);
    }

    enum Foo {
        BAR
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM