Можно ли вообще преобразовать перечисления одного и того же типа из разных классов в Java? - PullRequest
0 голосов
/ 04 января 2019

У меня есть внешняя модель с примерно 20 классами, которую я должен использовать, но не могу изменить (в коде ниже примеров: FirstExtClass, SecondExtClass).В каждом из этих классов есть enum, который является его внутренним классом (код ниже: 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;
}

Мой вопрос: возможно ли создать такую ​​универсальную функцию?

Ответы [ 3 ]

0 голосов
/ 04 января 2019

Вот пример кода для вас.Вам нужен 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
    }

}
0 голосов
/ 04 января 2019

Вы можете сделать это , если имена значений перечислений вашей и внешней модели равны, преобразовав внешнее перечисление в String, а затем преобразовав эту строку обратно в ваше перечисление следующим образом:

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

Это выдаст IllegalArgumentException в случае, если не будет найдено подходящего перечисления из EnumFromMyModel.

Тем не менее, я бы предпочел не использовать это и создать все эти 20 методов, которые вы упомянули иявное преобразование каждого значения перечисления безопасным способом времени компиляции.ИМХО, польза от безопасности при компиляции перевешивает выгоду от необходимости писать немного меньше кода.

0 голосов
/ 04 января 2019

Если я правильно понял вопрос, вы ищете что-то вроде следующего кода:

private static <T extends Enum> EnumFromMyModel genericConvert(T input) {
    return input.name().equals(/*????*/) ?
            EnumFromMyModel.FIRST_VALUE :
            EnumFromMyModel.SECOND_VALUE;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...