【问题标题】:Generic Input Parameter Compilation Error With Enum带有枚举的通用输入参数编译错误
【发布时间】:2019-08-13 06:16:06
【问题描述】:

我有一个如下的 Java 枚举类。我正在尝试将 A 类型布尔转换为 B 类型。为此,我将工厂与 Generic 一起使用。但是这里getInstance()方法实现的代码编译成功,而getInstance1()方法实现却失败了。

public enum FactoryEnum {

    BOOLEAN {

        @SuppressWarnings("unchecked")
        @Override
        public IConverter<ABoolean, BBoolean> getInstance() {// Compiled Successfully
            return new BooleanConverter();
        }


        @SuppressWarnings("unchecked")
        @Override
        public IConverter<ABoolean, BBoolean> getInstance(BBoolean bacStacDataType) { // Compilation Failed
            return new BooleanConverter(bacStacDataType);
        }

    };

    public abstract <M extends IADataType, R extends IBDataType> IConverter<M, R> getInstance();

    public abstract <M extends IADataType, R extends IBDataType> IConverter<M, R> getInstance1(R data);


    // A Type
    public interface IADataType {

    }

    public class ABoolean implements IADataType {

    }

    // B Type
    public interface IBDataType {

    }

    public class BBoolean implements IBDataType {

    }

    //Converter to Convert Data From A to B
    public interface IConverter<M, R> {

    }

    public class BooleanConverter implements IConverter<ABoolean, BBoolean> {


        public BooleanConverter() {

        }

        public BooleanConverter(BBoolean boolean1) {

        }
    }
}

你能帮我理解一下背后的原因吗?因为在第一种方法中也使用相同的通用参数 R 作为回报,它正在成功编译。但是当它作为输入参数传递时,它就失败了。

【问题讨论】:

    标签: java generics enums factory


    【解决方案1】:

    这个签名:

    public abstract <M extends IADataType, R extends IBDataType> IConverter<M, R> getInstance1(R data);
    

    表示该方法的实现必须采用任何 R(在界限内)。

    您正在尝试实现它以获取特定的 R。

    这根本行不通,因为它不是替代等效的。

    另外,您应该非常警惕这些@SuppressWarnings("unchecked") 注释。仅禁止您可以推理的警告实际上是安全的;这些不是。


    如果您希望枚举值具有不同的类型,则不能使用枚举。最终,枚举值只是包含类中的静态最终字段。

    因此,只需定义一个类,然后您就可以使用类级别的类型变量来限制特定类型。

    public class FactoryClass<M extends IADataType, R extends IBDataType> {
    
        public static final FactoryClass<ABoolean, BBoolean> BOOLEAN = new FactoryClass<ABoolean, BBoolean>() {
    
            @Override
            public BooleanConverter getInstance() {
                return new BooleanConverter();
            }
    
            @Override
            public BooleanConverter getInstance(BBoolean bacStacDataType) {
                return new BooleanConverter(bacStacDataType);
            }
    
        };
    
        public abstract IConverter<M, R> getInstance();
    
        public abstract IConverter<M, R> getInstance1(R data);
    }
    

    【讨论】:

    • 有点困,但R super BBoolean 是否允许编译?我知道 PECS,只是现在不想推理它。
    • @Rogue 考虑到您不能指定具有下限的类型变量,不。下限只能与通配符一起使用。
    • 啊,你说得对。感谢您再次为我消除通配符/类型变量之间的界限。
    猜你喜欢
    • 2015-03-13
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2013-02-18
    相关资源
    最近更新 更多