【问题标题】:Is this possible to generically convert enum of the same type from different classes in java?这是否可以从java中的不同类一般转换相同类型的枚举?
【发布时间】:2019-01-04 09:43:38
【问题描述】:

我有一个包含大约 20 个类的外部模型,我必须使用它,但不能修改(在下面的代码示例中:FirstExtClassSecondExtClass)。在这些类中的每一个中都有一个枚举,它是它的内部类(代码如下:TheSameEnum)。我将它翻译成我的模型,我希望这些枚举中的每一个都只是一种类型:EnumFromMyModel。我已经使用许多函数解决了这个问题,将外部枚举转换为我的枚举(下面有 2 个示例,但要完全转换它们,我需要 20 种复制粘贴方法,如下所示。

我正在尝试创建一个通用函数,它将以 TheSameEnum 作为参数的类并返回 EnumFromMyModel(类似于下面代码中的第三个函数)。

private static EnumFromMyModel 
convertFirstEnumFromExternalModelToEnumFromMyModel(FirstExtClass.TheSameEnum input) {
    return input.equals(FirstExtClass.TheSameEnum.FIRST_VALUE) ?
            EnumFromMyModel.FIRST_VALUE :
            EnumFromMyModel.SECOND_VALUE;
}

private static EnumFromMyModel convertSecondEnumFromExternalModelToEnumFromMyModel(SecondExtClass.TheSameEnum input) {
    return input.equals(SecondExtClass.TheSameEnum.FIRST_VALUE) ?
            EnumFromMyModel.FIRST_VALUE :
            EnumFromMyModel.SECOND_VALUE;
}


private static <T> EnumFromMyModel genericConvert(T input) {
    return input.equals(/*????*/) ?
            ScopeUsageLimit.FIRST_VALUE :
            ScopeUsageLimit.SECOND_VALUE;
}

我的问题是:这有可能创建这样的通用函数吗?

【问题讨论】:

    标签: java generics methods


    【解决方案1】:

    这里有一些示例代码供您参考。你需要toGeneric 方法。

    public class App {
        public static void main(String[] args) {
            Generic genericFirst1 = toGeneric(Specialized1.FIRST);
            Generic genericFirst2 = toGeneric(Specialized2.FIRST);
            assert genericFirst1 == genericFirst2;
    
            Specialized1 specialized1 = toSpecialized(Generic.SECOND, Specialized1.class);
            assert specialized1 == Specialized1.SECOND;
        }
    
        private static <T extends Enum<?>>T toSpecialized(Generic v, Class<T> specialized1Class) {
            try {
                return (T) specialized1Class.getField(v.name()).get(null);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        private static Generic toGeneric(Enum<?> e) {
            return Generic.valueOf(e.name());
        }
    
        enum Generic {
            FIRST, SECOND
        }
    
        enum Specialized1 {
            FIRST, SECOND
        }
    
        enum Specialized2 {
            FIRST, SECOND
        }
    
    }
    

    【讨论】:

    • 不使用反射来获取字段,您也可以像这样从字符串中查找枚举:return Enum.valueOf(specialized1Class, v.name());
    【解决方案2】:

    如果我正确理解了这个问题,您正在寻找类似于以下代码的内容:

    private static <T extends Enum> EnumFromMyModel genericConvert(T input) {
        return input.name().equals(/*????*/) ?
                EnumFromMyModel.FIRST_VALUE :
                EnumFromMyModel.SECOND_VALUE;
    }
    

    【讨论】:

      【解决方案3】:

      您可以这样做如果通过将外部枚举转换为String,然后将此字符串转换回您的枚举,您和外部模型的枚举值名称相等: p>

      private static EnumFromMyModel genericConvert(Enum<?> input) {
        return EnumFromMyModel.valueOf(input.name());
      }
      

      如果找不到来自 EnumFromMyModel 的匹配枚举,这将抛出一个 IllegalArgumentException

      不过,我宁愿不使用它,而是创建您提到的所有 20 种方法,并以编译时安全的方式显式转换每个枚举值。恕我直言,编译时安全的好处超过了编写更少代码的好处。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-29
        • 2022-01-20
        • 2013-09-26
        相关资源
        最近更新 更多