首页 > 解决方案 > 为什么枚举构造函数在 REST 类中只调用一次?

问题描述

我正在通过本教程学习 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但为什么类中的所有OrderService.Instance对象都OrderResource引用同一个对象 - 因此,OrderService.Instance仅当OrderResource第一次调用其中的一个方法并且所有后续调用都引用同一个对象时才为空考虑到OrderService它不是单例并且构造函数不是私有的,这不再是 null 了。

标签: javarestenumsconstructorsingleton

解决方案


枚举本质上是一种类型,它明确列出了该类型可以采用的值。例如。enum E { fee, foe, fie. fum }表示 E 类型的变量可以具有 4 个给定值之一,而不能具有其他值。

每个可能的值都需要并且只构造一次。

您的枚举仅列出了一个可能的值“实例”。这一个值只构造一次 - 导致总共有一个构造函数调用。

您的 OrderService 构造函数非常奇怪,因为它所做的似乎与枚举完全无关。调用构造函数来构造“Instance”的值,但它没有做任何与此相关的事情。

我认为也许您从根本上误解了枚举的性质。考虑这个陈腐的例子:

    enum Colour { RED; BLUE; GREEN; }

这里的构造函数是隐式的。RED被构建;BLUE 已构建;构建绿色。所有这一切都在使用 Color 之前。

我们现在讨论的内容相当于想知道为什么只有一个 RED。


推荐阅读