Почему конструктор Enum вызывается только один раз в классе REST? - PullRequest
1 голос
/ 12 июля 2020

Я изучаю REST по этому руководству. Сначала запускается: ClientAllOrders(), что создает 5 заказов. Затем он запускает: ClientDeleteById(), который удаляет заказы 2 и 4. Затем он запускает ClientAllOrders() и получает все заказы, кроме заказов 2, 4. Он создает заказы здесь:

Пример удаления из руководства

public enum OrderService {
    Instance;
    private Map<Integer, Order> orders = new HashMap<>();

    OrderService() {
        Instant instant = OffsetDateTime.now().toInstant();
        for (int i = 1; i <= 5; i++) {
            Order order = new Order();
            order.setId(i);
            order.setItem("item " + i);
            order.setQty((int) (1 + Math.random() * 100));
            long millis = instant.minus(Period.ofDays(i))
                                 .toEpochMilli();
            order.setOrderDate(new Date(millis));
            orders.put(i, order);
        }
    }
//---
}

Это методы GET и DELETE:

@Path("/orders")
@Produces({MediaType.APPLICATION_XML, MediaType.TEXT_PLAIN})
public class OrderResource {

@GET
    public Collection<Order> getOrders() {
        return OrderService.Instance.getAllOrders();
    }

    @DELETE
    @Path("{id}")
    public boolean deleteOrderById(@PathParam("id") int id) {
        return OrderService.Instance.deleteOrderById(id);
    }
//…
}

Если я не остановлю / не запустил сервер или не разверну новую войну, OrderService.constructor вызывается только одним , независимо от того, сколько раз вызывается getOrders() или deleteOrderById(). OrderService.constructor вызывается только тогда, когда объект OrderService.Instance имеет значение NULL, но почему все объекты OrderService.Instance в классе OrderResource относятся к одному и тому же объекту - следовательно, OrderService.Instance имеет значение NULL только тогда, когда один из методов в OrderResource вызывается в первый раз, а все последующие вызовы относятся к одному и тому же объекту, который больше не является нулевым, учитывая, что OrderService не является синглтоном, а конструктор не является частным.

Ответы [ 2 ]

2 голосов
/ 12 июля 2020

Короткий ответ: перечисления неявно являются c и, как говорит Энди Тернер в своем комментарии, поэтому инициализируются только один раз. См. эту замечательную статью для подробностей. Подробнее см. Остальные.

Цитирование ранее упомянутой статьи (см. Главу 1.2. Java объявление перечисления ), если у вас есть перечисление вроде:

public enum Direction {
    EAST, WEST, NORTH, SOUTH;
}

Логически каждое перечисление является экземпляром самого перечисляемого типа. Таким образом, данное перечисление можно увидеть, как показано ниже. JVM внутренне добавляет к этому классу методы порядкового номера и значения, которые мы можем вызывать при работе с enum.

final class Direction extends Enum<Direction>  {
    public final static Direction EAST = new Direction();
    public final static Direction WEST = new Direction();
    public final static Direction NORTH = new Direction();
    public final static Direction SOUTH = new Direction();
}
2 голосов
/ 12 июля 2020

Перечисление - это тип, который явно перечисляет значения, которые может принимать что-то из этого типа. Например. enum E { fee, foe, fie. fum } говорит, что переменная типа E может иметь одно из 4 заданных значений и никакое другое.

Каждое возможное значение должно быть построено и создается только один раз.

Ваше enum перечисляет только одно возможное значение - «Экземпляр». Это одно значение создается ровно один раз, что приводит к вызову одного конструктора.

Ваш конструктор OrderService очень странный, поскольку то, что он делает, кажется, вообще не связано с перечислением. Конструктор вызывается для конструирования значения «Экземпляр», но при этом ничего не делает с этим.

Я думаю, что, возможно, вы в корне неправильно понимаете природу перечисления. Рассмотрим этот избитый пример:

    enum Colour { RED; BLUE; GREEN; }

Конструктор здесь неявный. КРАСНЫЙ построен; СИНИЙ построен; ЗЕЛЕНЫЙ построен. Все это предшествует любому использованию цвета.

То, что мы сейчас обсуждаем, эквивалентно удивлению, почему есть только один КРАСНЫЙ.

...