Перечисляемые типы (enum) в Java

12-10-21 Java 1

В этом уроке мы рассмотрим перечисляемые типы в Java.

Тип enum — это тип, поля которого состоят из набора некоторых констант. Простой пример — стороны света, такой объект будет содержать 4 константы: NORTH, SOUTH, EAST, и WEST. Переменные объявлены большими буквами, потому что это константы.

Синтаксис

Для объявления используется ключевое слово enum. Например, нам необходимо перечислить дни недели:

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY
}

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

public class EnumTest {
    Day day;

    public EnumTest(Day day) {
        this.day = day;
    }

    public void tellItLikeItIs() {
        switch (day) {
            case MONDAY:
                System.out.println("Mondays are bad.");
                break;

            case FRIDAY:
                System.out.println("Fridays are better.");
                break;

            case SATURDAY: case SUNDAY:
                System.out.println("Weekends are best.");
                break;

            default:
                System.out.println("Midweek days are so-so.");
                break;
        }
    }

    public static void main(String[] args) {
        EnumTest firstDay = new EnumTest(Day.MONDAY);
        firstDay.tellItLikeItIs();
        EnumTest thirdDay = new EnumTest(Day.WEDNESDAY);
        thirdDay.tellItLikeItIs();
        EnumTest fifthDay = new EnumTest(Day.FRIDAY);
        fifthDay.tellItLikeItIs();
        EnumTest sixthDay = new EnumTest(Day.SATURDAY);
        sixthDay.tellItLikeItIs();
        EnumTest seventhDay = new EnumTest(Day.SUNDAY);
        seventhDay.tellItLikeItIs();
    }
}

Данная программа выведет:

Mondays are bad.
Midweek days are so-so.
Fridays are better.
Weekends are best.
Weekends are best.

Перечисляемые типы в языке Java — более эффективный инструмент, чем аналоги в других языках. Объявление типа enum определяет класс (enum type), который может содержать методы и другие поля. Компилятор автоматически добавляет некоторые методы, когда создает тип enum. Например, он имеет статический метод values, который возвращает массив, содержащий значения объекта в порядке их объявления. Этот метод обычно используется в комбинации с конструкцией for-each для обхода всех значений типа enum. Например, следующий код обходит все планеты:

for (Planet p : Planet.values()) {
 System.out.printf("Your weight on %s is %f%n",
 p, p.surfaceWeight(mass));
 }

В следующем примере, Planet — это перечисляемый тип, который содержит планеты солнечной системы. Они объявлены с их физическими свойствами: масса и радиус.

Константы объявлены вместе со значениями радиуса и массы. Эти значения передаются конструктору при создании константы. Синтаксис языка требует, чтобы константы объявлялись до остальных полей и методов, также после объявления необходима точка с запятой. Конструктор enum типа должен быть private или package-private, он автоматически создает перечисленные константы. Нельзя самостоятельно вызвать enum конструктор. В дополнение к конструктору и свойствам, Planet имеет методы для вычисления гравитации и веса объекта на каждой планете.

public enum Planet {
    MERCURY (3.303e+23, 2.4397e6),
    VENUS   (4.869e+24, 6.0518e6),
    EARTH   (5.976e+24, 6.37814e6),
    MARS    (6.421e+23, 3.3972e6),
    JUPITER (1.9e+27,   7.1492e7),
    SATURN  (5.688e+26, 6.0268e7),
    URANUS  (8.686e+25, 2.5559e7),
    NEPTUNE (1.024e+26, 2.4746e7);

    private final double mass;   // в килограммах
    private final double radius; // в метрах
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    private double mass() { return mass; }
    private double radius() { return radius; }

    // гравитационная постоянная
    public static final double G = 6.67300E-11;

    double surfaceGravity() {
        return G * mass / (radius * radius);
    }
    double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java Planet <earth_weight>");
            System.exit(-1);
        }
        double earthWeight = Double.parseDouble(args[0]);
        double mass = earthWeight/EARTH.surfaceGravity();
        for (Planet p : Planet.values())
           System.out.printf("Your weight on %s is %f%n",
                             p, p.surfaceWeight(mass));
    }
}

Если запустить Planet.class из командной строки с параметром 175, то программа выведет:

$ java Planet 175
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413

На этом все 🙂 Не пропустите новые уроки!

Хочешь получать статьи на почту?

Подпишись на обновления!
* Ваш email не будет разглашен/продан. Вы сможете отписаться в любое время.

1 Комментарий

  1. Roma:

    Думаю, куда более понятно было бы описать перечисления как КЛАССЫ, которые имеют уже известный набор объектов.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *