为什么 Enum 构造函数在 REST class 中只被调用一次?

Why Enum constructor is called only once in REST class?

我正在通过本教程学习 REST。它首先运行:ClientAllOrders(),创建 5 个订单。然后它运行:ClientDeleteById(),删除订单 2 和 4。然后它运行 ClientAllOrders(),并获取除订单 2、4 之外的所有订单。它在此处创建订单:

Tutorial Delete Example

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);
    }
//…
}

除非我stop/start服务器或者部署一个新的war,否则OrderService.constructor不管getOrders()或[=18=多少次都只调用一次] 被称为。 OrderService.constructor 仅在 OrderService.Instance 对象为 null 时被调用,但为什么 OrderResource class 中的所有 OrderService.Instance 对象都引用同一个对象 - 因此 OrderService.Instance 仅当首次调用 OrderResource 中的方法之一时为 null,所有后续调用都引用不再为 null 的同一对象,考虑到 OrderService 不是单例且构造函数不是私有的。

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

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

您的枚举恰好列出了一个可能的值,'Instance'。这个值仅构造一次 - 导致总共调用一次构造函数。

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

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

    enum Colour { RED; BLUE; GREEN; }

这里的构造函数是隐式的。 RED 已构建;蓝色构造;绿色建造。所有这些都在使用颜色之前。

我们现在讨论的就是想知道为什么只有一个红色。

简短的回答是枚举是隐式静态的,正如 Andy Turner 在他的评论中所说的那样,因此只初始化了一次。有关详细信息,请参阅 this great article。详情见其余

引用前面提到的文章(参见第 1.2 章。Java 枚举声明),如果你有这样的枚举:

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

Logically, each enum is an instance of enum type itself. So given enum can be seen as below declaration. JVM internally adds ordinal and value methods to this class which we can call while working with 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();
}