Все еще часто определяете константы? не пытайтесь использовать enum вместо этого

Java задняя часть
Все еще часто определяете константы? не пытайтесь использовать enum вместо этого

«Это первый день моего участия в ноябрьском испытании обновлений, ознакомьтесь с подробностями события:Вызов последнего обновления 2021 г."

  • Готовьтесь к весеннему набору или летней стажировке 2022 года, и я желаю вам всем миллион очков прогресса каждый день!Day5

  • В этой статье кратко изложено «Правильное использование перечисления Java», которое в будущем будет ежедневно обновляться~

  • Для получения знаний, таких как «Приступая к освоению Redis» и «Параллельное программирование», вы можете обратиться к моим предыдущим блогам.

  • Верь в себя, живи сильнее, Пока ты жив, ты должен открыть дорогу в горах и построить мост через воду! Жизнь, ты на меня надави, я подарю тебе чудо!

image.png

1. Введение

Я не знаю, видели ли вы код, подобный следующему, в вашем собственном проекте:

public static void fruitsHandle(String fruits) {

    switch (fruits) {
        case "Apple":
            // TODO
            break;
        case "Banana":
            // TODO
            break;
        case "Orange":
            // TODO
            break;
        default:
            throw new IllegalStateException("Unexpected value: " + fruits);
    }

}

Вышеупомянутая ситуация встречается очень редко, и Xiaomengxin вообще не повторяет напрямую определение строки в методе для сравнения, а определяет ее как константу или равномерно извлекает как константный класс. Поэтому я обычно вижу такой код (Сяо Ян часто видит такой код в проектах, но Сяо Ян не осмеливается ничего сказать 😄😄):

private static final String APPLE = "Apple";
private static final String BANANA = "Banana";
private static final String ORANGE = "Orange";

public static void fruitsHandle(String fruits) {

    switch (fruits) {
        case APPLE:
            // TODO
            break;
        case BANANA:
            // TODO
            break;
        case ORANGE:
            // TODO
            break;
        default:
            throw new IllegalStateException("Unexpected value: " + fruits);
    }

}

Вышеупомянутая ситуация очень часто встречается в нашем коде;Это требует, чтобы программист предоставил набор фиксированных констант, и конкретные члены этого набора фиксированных констант известны во время разработки или компиляции.В это время мы должны использовать перечисление.

Тип перечисления — это тип, состоящий из фиксированного набора констант, составляющих допустимые значения.


2. Преимущества

Использование перечислимых типов может дать много преимуществ по сравнению с прямым определением констант.


2.1 Безопасность типа

Определите простое перечисление мяса и перечисление фруктов соответственно

// 肉类枚举
public enum MeetEnums {

    BEEF,
    PORK,
    FISH;

}
// 水果枚举
public enum FruitsEnums {

    APPLE,
    BANANA,
    ORANGE;

}

Мы модифицируем приведенный выше код и модифицируем тип входного параметра.

public static void fruitsHandle(FruitsEnums fruits) {

    switch (fruits) {
        case APPLE:
            // TODO
            break;
        case BANANA:
            // TODO
            break;
        case ORANGE:
            // TODO
            break;
        default:
            throw new IllegalStateException("Unexpected value: " + fruits);
    }

}

Вы можете видеть, что определение типа перечисления обеспечивает безопасность типа функции.Если вы определяете константу, вы не можете проксировать этот эффект.

2.2 Перечисление может предоставить больше информации

Перечисление — это, по сути, класс, который может определять свойства и методы.Мы можем определить нужные методы в классе перечисления или расширить базовую информацию, предоставляемую перечислением, с помощью свойств.

Например, наиболее распространенный HttpStatus, когда мы занимаемся веб-разработкой, определяется как класс перечисления в фреймворке springframework, который содержит не только код ответа Http, но и статус описания.

public enum HttpStatus {

	OK(200, "OK"),
    NOT_FOUND(404, "Not Found"),
    INTERNAL_SERVER_ERROR(500, "Internal Server Error");
    
    private final int value;
    private final String reasonPhrase;

    private HttpStatus(int value, String reasonPhrase) {
        this.value = value;
        this.reasonPhrase = reasonPhrase;
    }
    
}

2.3 Предоставляйте больше услуг с помощью функций

Кроме того, в HttpStatus также вложен класс перечисления Series, который может помочь классу перечисления HttpStatus оценить текущее состояние перечисления по режиму statusCode / 100 is1xxInformational, is2xxSuccessful, is3xxRedirection, is4xxClientError, is5xxServerError и т. д.

public static enum Series {
        INFORMATIONAL(1),
        SUCCESSFUL(2),
        REDIRECTION(3),
        CLIENT_ERROR(4),
        SERVER_ERROR(5);

        private final int value;

        private Series(int value) {
            this.value = value;
        }

        public int value() {
            return this.value;
        }

        public static HttpStatus.Series valueOf(HttpStatus status) {
            return valueOf(status.value);
        }

        public static HttpStatus.Series valueOf(int statusCode) {
            HttpStatus.Series series = resolve(statusCode);
            if (series == null) {
                throw new IllegalArgumentException("No matching constant for [" + statusCode + "]");
            } else {
                return series;
            }
        }

        @Nullable
        public static HttpStatus.Series resolve(int statusCode) {
            int seriesCode = statusCode / 100;
            HttpStatus.Series[] var2 = values();
            int var3 = var2.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                HttpStatus.Series series = var2[var4];
                if (series.value == seriesCode) {
                    return series;
                }
            }

            return null;
        }
    }

2.4 Получить все определенные типы

Все классы enum автоматически генерируютvalues() он может возвращать набор массивов текущего определенного класса перечисления, поэтому очень удобно проходить все перечисления, определенные этим классом перечисления. Например, мы просто преобразуем класс перечисления MeetEnums:

public enum MeetEnums {

    BEEF("牛肉"),
    PORK("猪肉"),
    FISH("鱼肉");

    String name;

    public String getName() {
        return name;
    }

    MeetEnums(String name) {
        this.name = name;
    }

    public static MeetEnums getMeetEnumsByName(String name) {
        MeetEnums[] values = values();
        Optional<MeetEnums> optional = Stream.of(values).filter(v -> v.getName().equals(name)).findAny();
        return optional.isPresent() ? optional.get() : null;
    }

}

Короче говоря, классы перечисления имеют много преимуществ перед константами, которые могут сделать код более чистым, красивым, безопасным и мощным. Хотя в большинстве случаев выбор классов перечислений происходит из-за определений констант, не всегда обязательно определять константы как перечисления, вы можете решать сами в конкретной ситуации!