Между интерфейсами и перечислениями, что лучше для объявления констант? Почему это так?
Интерфейсы против перечислений
Ответ 1
Всегда лучше использовать Enums для объявления констант, поскольку цель интерфейсов находится на совершенно другом уровне. Да, есть много интерфейсов, которые имеют константы public static final
, но я чувствую, что исключительная задача перечисления - предоставить вам эти константы.
Ответ 2
Если у ваших констант есть причина иметь определенный тип, если им нужно какое-то поведение (т.е. методы) или если они являются композитами других значений, enum
- это путь.
Например, предположим, что вы реализуете карточную игру, и хотите представить значения и костюмы:
enum Rank {
ACE, TWO, THREE, FOUR, FIVE, SIX, SEVEN,
EIGHT, NINE, TEN, JACK, QUEEN, KING;
}
enum Suit { SPADES, CLUBS, DIAMONDS, HEARTS }
Там теперь невозможно создать карты с фиктивными костюмами или рядами.
Иногда, однако, вас просто интересует наличие кучи часто используемых значений, объявленных где-то. В этом случае их размещение в enum
просто было бы ненужным усилием, так как эти константы - это просто инструмент, который спасет нас от запоминания всех десятичных знаков, скажем, π, когда мы вычисляем окружность круга или что-то в этом роде. Что выглядит лучше?
// Using enum:
enum MathConstant {
PI(3.14159265358979323846), E(2.7182818284590452354);
private final double value;
MathConstant(double v) { value = v; }
public double value() { return value; }
}
// Usage:
double circumference = MathConstant.PI.value() * diameter;
// Using a constant class:
final class MathConstants {
private MathConstants() { throw new UnsupportedOperationException(); }
public static final double PI = 3.14159265358979323846,
E = 2.7182818284590452354;
}
// Usage:
double circumference = MathConstants.PI * diameter;
Как для интерфейсов: никогда не помещайте константы в интерфейс. Шаблон "постоянный интерфейс" плох (обоснование), и единственный аргумент для его использования был признан недействительным, поскольку import static
был добавлен в Java.
Ответ 3
Интерфейсы предназначены для определения общего поведения, перечисления для определения общих значений.
Enum представляет собой реальное значение, которое можно сравнить с другим значением или легко хранить в базе данных. Вы также можете иметь флаг-enum (в С#, не знаете на Java), который позволяет выполнять двоичные операции с значениями перечисления (AND, OR, XOR и т.д.).
Ответ 4
Если вы работаете с Java 5 или новее, то Enum - это путь. Единственное исключение - если ваш список const открыт и может быть расширен. Перечисления не могут быть расширены. Другое исключение - если это одиночные значения, такие как MAX_INTEGER.