Эта статья написанаyanglbme Оригинал, впервые опубликованный в публичном аккаунте"Сообщество открытого исходного кода Doocs", несанкционированное воспроизведение запрещено.
Кажется, что в теме констант в Java много путаницы. Некоторые люди используют целые числа или строки для определения констант, в то время как другие используют перечисления. Я также сталкивался с константами, определенными в собственном интерфейсе, который должен реализовать класс, использующий константу. Эту стратегию часто называют шаблоном проектирования констант интерфейса.
В этой статье я представлю в обеих Java сохраненные константы наиболее распространенных стратегий:целое числоиперечислить. Во-первых, всякий раз, когда вы решите использовать константу, вы должны убедиться, что константа не меняется с течением времени, чтобы избежать перекомпиляции.
Сцены
Возьмем очень распространенный пример констант:Weekday
.
Предположим, у нас есть класс в нашем интернет-магазине, который представляет собой заказ, порядок, в котором мы хотим отслеживать, какой день недели возникает заказ.
Наш класс выглядит так:
public class Order {
private [datatype] weekDay;
public [datatype] getWeekDay() {
return weekDay;
}
public void setWeekDay([datatype] weekDay) {
this.weekDay = weekDay;
}
}
Обратите внимание, что класс пока не будет компилироваться,datatype
Просто заполнитель для типа константы, который мы собираемся использовать.
Определить константы с целыми числами
Одним из наиболее распространенных способов определения констант в Java является использование целых чисел, где целые переменные используютstatic final
ретушь.
public static final int MONDAY = 0;
public static final int TUESDAY = 1;
public static final int WEDNESDAY = 2;
public static final int THURSDAY = 3;
public static final int FRIDAY = 4;
public static final int SATURDAY = 5;
public static final int SUNDAY = 6;
Первый вопрос, который следует учитывать при определении целочисленных констант, — куда их поместить.
Помещаем ли мы их непосредственно в класс ORDER? Тем не менее, мы поместили их в отдельный класс.
Так как Weekday не обязательно применяется только к объектам типа Order, мы определяем их в отдельном классе Weekday.
public class WeekDay {
private WeekDay() {}
public static final int MONDAY = 0;
public static final int TUESDAY = 1;
public static final int WEDNESDAY = 2;
public static final int THURSDAY = 3;
public static final int FRIDAY = 4;
public static final int SATURDAY = 5;
public static final int SUNDAY = 6;
}
Вы, возможно, заметили закрытый конструктор, это сделано для того, чтобы клиенты не создавали экземпляр класса. Класс содержит только статические переменные, которые не привязаны к объектам, поэтому нет необходимости создавать экземпляр класса.
Теперь, когда нам нужно установить конкретную дату для Заказа, мы можем сделать это следующим образом:
Order order = new Order();
order.setWeekDay(WeekDay.MONDAY);
Когда мы хотим проверить, произошел ли заказ в пятницу, мы можем просто вызвать метод получения:
if (order.getWeekDay() == WeekDay.FRIDAY) {}
Все идет нормально. Кажется, что с этой конструкцией проблем нет.
Ну, предположим, вы вернетесь к этому коду через год, и вы должны проверить, будет ли заказ в понедельник. Вы можете совсем забыть о буднях (не исключайте такой возможности)...
В этом случае можно попробовать следующее:
if (order.getWeekDay() == 1) {}
Если полностью забыть о классе WeekDay, этот код имеет смысл. Понедельник — первый день недели, поэтому день недели должен быть равен 1, верно? Но нет, нет, потому что статическая переменная типа Monday определена как 0 в нашем классе Weekday!
Это хороший пример того, почему вам следует избегать целочисленных констант.Они подвержены ошибкам, грязны и трудны для отладки..
Определение констант с перечислениями
Другой способ определения констант в Java — использование перечислений.
При использовании перечисления константный класс будет выглядеть так:
public enum WeekDay {
MONDAY,
TUESDAY,
WEDNESDAY,
THURSDAY,
FRIDAY,
SATURDAY,
SUNDAY
}
Обратите внимание, что здесь нет приватных конструкторов, и вам не нужно заставлять класс не создавать экземпляры, потому чтоПеречисления не создаются по умолчанию!
Синтаксис установки дня недели для заказа точно такой же, как и при использовании целочисленной константы:
order.setWeekDay(WeekDay.MONDAY);
Также нет разницы, сможем ли мы обработать заказ в пятницу:
if (order.getWeekDay() == WeekDay.FRIDAY) {}
Тем не менее, основные различия:Это единственный способ установить и сравнить значение переменной дня недели в классе Order..
если вы используетеorder.setWeekDay(1);
иif(order.getWeekDay()== 1)
, приведет к тому, что компилятор выдаст ошибку, потому что когда вы пытаетесь использовать переменные типа integer, они должны быть типа WeekDay !
Вспомните, что вы совсем забыли о константном классе «День недели».Для перечислений это больше не проблема!如果你尝试使用整数代替 WeekDay 枚举的成员,则编译器将简单地引发一个错误,告诉你需要使用 WeekDay 枚举。
Другими словами, единственный способ проверить, был ли заказ в пятницу, это:
if (order.getWeekDay() == WeekDay.FRIDAY) {}
Вам больше не нужно запоминать константные классы, и если какой-либо клиент захочет использовать ваш код, вам не придется задаваться вопросом, действительно ли понедельник представлен 0 или 1.
Я надеюсь, что этот пример проясняет, почему вы должны рассмотреть возможность использования перечислений для целых чисел при определении констант. Перечисления сделают наш код менее подверженным ошибкам, его будет легче читать и поддерживать!
Наконец, рекомендуется прочитатьДействующая Java, 3-е издание [2019]эта хорошая книга.
яДокументы технического сообщества GitHubИнициатор, добро пожаловать в мой публичный аккаунт WeChat «Сообщество открытого исходного кода Doocs», оригинальные технические статьи будут размещены как можно скорее.