简体   繁体   English

Enum *似乎*被多次初始化,构造函数被多次调用。 如果我是对的,那为什么?

[英]Enum *seems* to be initialized more than once, the constructor is called more than once. If I’m right, then why?

I'm reading thru this tutorial:我正在阅读本教程:

JAX-RS Delete Example JAX-RS 删除示例

It first runs: ClientAllOrders() , which creates 5 orders.它首先运行: ClientAllOrders() ,它创建 5 个订单。 Then it runs: ClientDeleteById() , which deletes orders 2 and 4. Then it runs ClientAllOrders() , and gets all orders except for orders 2, 4. It creates orders here:然后运行: 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);
        }
    }
//---
}

Note that OrderResource is not a Singleton , so by default a new instance of the resource class is created for each new request, however, the OrderService.constructor is called only ones and Enum in initialized only once as expected.请注意, OrderResource不是Singleton ,因此默认情况下,会为每个新请求创建资源 class 的新实例,但是, OrderService.constructor仅调用 one 并且Enum仅按预期初始化一次。

The above scenario results in this output:上述场景导致了这个 output:

// ClientAllOrders:

Order{id=1, item='item 1', qty=62, orderDate=Fri Jul 24 18:27:51 EDT 2020}
Order{id=2, item='item 2', qty=100, orderDate=Thu Jul 23 18:27:51 EDT 2020}
Order{id=3, item='item 3', qty=29, orderDate=Wed Jul 22 18:27:51 EDT 2020}
Order{id=4, item='item 4', qty=28, orderDate=Tue Jul 21 18:27:51 EDT 2020}
Order{id=5, item='item 5', qty=28, orderDate=Mon Jul 20 18:27:51 EDT 2020}

// ClientDeleteById – deletes orders 2 and 4:

true
true

// Run ClientAllOrders again:

Order{id=1, item='item 1', qty=62, orderDate=Fri Jul 24 18:27:51 EDT 2020}
Order{id=3, item='item 3', qty=29, orderDate=Wed Jul 22 18:27:51 EDT 2020}
Order{id=5, item='item 5', qty=28, orderDate=Mon Jul 20 18:27:51 EDT 2020}

However, if I add this line in ClientAllOrders :但是,如果我在ClientAllOrders添加这一行:

Collection<Order> c = OrderService.Instance.getAllOrders();
c.forEach(System.out::println);

Then OrderService.constructor is called again, and the map now has 5 new orders in it.然后再次调用OrderService.constructor ,map 现在有 5 个新订单。 Why unlike the REST requests that all share the same Enum object, here, Enum was initialized again and the constructor() was called again creating 5 new orders?为什么不像REST请求所有共享相同的Enum object,在这里,再次初始化Enum并再次调用constructor()创建 5 个新订单?

    public class ClientAllOrders {
        
        public static void main(String[] args) {
            Client client = ClientBuilder.newClient();
            
            //get all  orders
            WebTarget allOrderTarget = client.target("http://localhost:8080/jaxrs-delete-example/orders");
    
            Response response = allOrderTarget.request().get();
            List<Order> orders = response.readEntity(new GenericType<List<Order>>() {});
            System.out.println("Orders by REST call:");
            orders.forEach(System.out::println);
            
// Added this line - Enum is initialized again and constructor called again, creating new orders:
            Collection<Order> c = OrderService.Instance.getAllOrders();
            System.out.println("Orders created again:");
            c.forEach(System.out::println);
        }
    }

This is the output if I run ClientAllOrders , note the orders created are different:这是 output 如果我运行ClientAllOrders ,请注意创建的订单不同:

Orders by REST call:
Order{id=1, item='item 1', qty=59, orderDate=Fri Jul 24 18:35:24 EDT 2020}
Order{id=2, item='item 2', qty=14, orderDate=Thu Jul 23 18:35:24 EDT 2020}
Order{id=3, item='item 3', qty=78, orderDate=Wed Jul 22 18:35:24 EDT 2020}
Order{id=4, item='item 4', qty=3, orderDate=Tue Jul 21 18:35:24 EDT 2020}
Order{id=5, item='item 5', qty=2, orderDate=Mon Jul 20 18:35:24 EDT 2020}

Orders created again:
Order{id=1, item='item 1', qty=1, orderDate=Fri Jul 24 18:35:24 EDT 2020}
Order{id=2, item='item 2', qty=53, orderDate=Thu Jul 23 18:35:24 EDT 2020}
Order{id=3, item='item 3', qty=76, orderDate=Wed Jul 22 18:35:24 EDT 2020}
Order{id=4, item='item 4', qty=31, orderDate=Tue Jul 21 18:35:24 EDT 2020}
Order{id=5, item='item 5', qty=25, orderDate=Mon Jul 20 18:35:24 EDT 2020}

The client and the server run in separate processes, in separate JVMs, independently.客户端和服务器在不同的进程、不同的 JVM 中独立运行。 The server has one version of enum OrderService , and the client has another.服务器有一个版本的enum OrderService ,而客户端有另一个。 Nothing links these two instances of the enum to each other.没有任何东西将枚举的这两个实例相互链接。

In your case, the "server" is an application server, where you deploy the web application "war" archive.在您的情况下,“服务器”是一个应用程序服务器,您在其中部署 web 应用程序“战争”存档。 The "client" is a separate Java program with a main method. “客户端”是一个单独的 Java 程序,带有一个main方法。 that you run from your IDE with the "run as Java application" action.您从 IDE 运行“作为 Java 应用程序运行”操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 这段代码的问题在于输出。 生产者生产不止一次。 为什么以及如何解决? - The problem of this code is in the output. Producer produce more than once. Why and how can I solve it? windowClosed多次触发。 这是错误还是功能? - windowClosed fires more than once. Is this a bug or a feature? Servlet不止一次被初始化? - Servlet is being initialized more than once? mousePressed函数似乎多次按下 - mousePressed function seems to press more than once DatagramSocket.receive() 被多次调用 - DatagramSocket.receive() is called more than once XPages:beforePageLoad运行了不止一次……为什么? - XPages: beforePageLoad runs more than once… Why? 为什么这个for循环不能多次循环? - Why is this for loop not looping more than once? Java:服务器不会多次通过tcp套接字接收消息。 - Java: Server not receiveing messages over tcp socket more than once. 手动触发的Azure Webjob多次触发。 返回409(冲突)错误 - Manually Triggered Azure Webjob is getting triggered more than once. Returning 409 (conflict) error Java - 多次从ArrayList中删除时出错。 (IllegalStateException异常) - Java - Error when removing from an ArrayList more than once. (IllegalStateException)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM