简体   繁体   中英

Is this possible to generically convert enum of the same type from different classes in java?

I have an external model with about 20 classes, which I have to use, but cannot modify (in code below examples: FirstExtClass , SecondExtClass ). In each of these classes there is an enum, which is its internal class (code below: TheSameEnum ). I am translating it into my model, in which I want each of these enums to be just one type: EnumFromMyModel . I have solved it using many functions, that convert external enums to my enums (2 examples are below, but to completely convert them I need 20 copy-paste methods like below.

I am trying to create one generic function, that would take a class with TheSameEnum as parameter and return EnumFromMyModel (something like third function in code below).

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;
}

My question is: is this possible to create such generic function?

Here is some sample code for you. You need toGeneric method.

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
    }

}

If I understand the question correctly, you are looking for something like the below code:

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

You can do this if the enum value names of your and the external model are equal by converting the external enum to String and then converting this string back to your enum like this:

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

This will throw an IllegalArgumentException in case no matching enum from EnumFromMyModel can be found.

Still, i'd rather not use this and create all those 20 methods you mentioned and explicitly convert each enum value in a compile time safe manner. IMHO, the benefit of having compile time safety outweighs the benefit of having to write a little less code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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