gpt4 book ai didi

java - Servlet 中的构造函数和 finalize() 方法

转载 作者:行者123 更新时间:2023-11-30 06:24:19 24 4
gpt4 key购买 nike

正如我们所知,init() 完成构造函数的工作,而 destroy() 与 servlet 的 finalize 方法相同,拥有构造函数和Servlet 中的 finalize() 方法。

现在的问题是:如果在Servlet中定义了一个构造函数和一个finalize()方法,它们会被调用吗?是不是就像我们将在构造函数中初始化的任何内容都将被 init() 中的内容覆盖,或者根本不会调用构造函数?

最佳答案

首先进行小的修正

让我们先回顾一些假设。更多详细信息,请参阅帖子的其余部分。

As we know init() does the job of constructor

不,它没有。它有很大的不同:

  • 声明一个throws ServletException
  • 声明一个 ServletConfig 参数,* 它调用其父构造函数(因为 Java 默认调用父构造函数的无参数)。

对于最后一点,在一般情况下这并不重要,因为 ServletHttpServlet 什么都不做,但是如果使用这些抽象类的扩展,那么你不应该假设 他们 也没有搞砸构造函数并在其中做事。虽然您可以从 init() 中选择不调用父级 init(),但父级的无参数构造函数将始终被调用。

[...] and destroy() the same of finalize method

不,不是。

there is no harm having a constructor and finalize method in a servlet

如果在构造函数和终结器中发生异常,可能会造成伤害,无论如何我肯定不建议使用它们,但建议坚持使用 init()destroy() 以符合规范。规范中未定义自定义构造函数和析构函数抛出的异常的异常处理规则,因此这些将是未定义的行为/容器特定的。

will they be called?

你尝试了吗?会发生什么?

(是的:no-arg 构造函数将为每个新线程实例调用,并且终结器将被调用...只要 GC 愿意。 )

is it like whatever we will initialize in constructor will be overriden with that in init() or constructor wont be called at all?

init() 不是构造函数。

您可以覆盖 init() 中在构造函数中初始化的某些内容(例如成员变量),或者撤消/还原您在构造函数中执行的操作。看不出这会有用的原因,但您可能可以。但它们不会相互抵消,如果那是你的意思的话。

为什么还要这样做?

我在这里问自己的问题更多:

  • 为什么您觉得这里需要自定义构造函数?
  • 为什么你觉得这里需要一个终结器? (或者实际上,一般来说?)

Servlet 生命周期

摘自 Servlet Lifecycle 上的 Java EE 6 教程部分:

  1. If an instance of the servlet does not exist, the web container
    • Loads the servlet class.
    • Creates an instance of the servlet class.
    • Initializes the servlet instance by calling the init method. Initialization is covered in Creating and Initializing a Servlet.
    • Invokes the service method, passing request and response objects. Service methods are discussed in Writing Service Methods.
  2. If it needs to remove the servlet, the container finalizes the servlet by calling the servlet’s destroy method. For more information, see Finalizing a Servlet.

[...]

Any number of exceptions can occur when a servlet executes. When an exception occurs, the web container generates a default page containing the following message:

A Servlet Exception Has Occurred

如何正确init()

让我们回顾 init() 上的 Javadoc (强调我的)

Called by the servlet container to indicate to a servlet that the servlet is being placed into service.

The servlet container calls the init method exactly once after instantiating the servlet. The init method must complete successfully before the servlet can receive any requests.

The servlet container cannot place the servlet into service if the init method

  • Throws a ServletException
  • Does not return within a time period defined by the Web server

因此,请注意不要在您的 init() 中做任何消耗过多的事情,以及只需要做一次的事情。如果它是所有请求都需要做的事情,那么在请求处理方法中做它(例如doGet(), doPost(), ...)。

另见 Creating and Initializing a ServletJava EE 6 Tutorial (and for Java EE 5)。

如何正确destroy()

Called by the servlet container to indicate to a servlet that the servlet is being taken out of service. This method is only called once all threads within the servlet's service method have exited or after a timeout period has passed. After the servlet container calls this method, it will not call the service method again on this servlet.

This method gives the servlet an opportunity to clean up any resources that are being held (for example, memory, file handles, threads) and make sure that any persistent state is synchronized with the servlet's current state in memory.

另见 Finalizing a ServletJava EE 6 Tutorial ( and for Java EE 5 )(诚然,他们在这里选词不当……)。

有关历史 Servlet 设计的更多信息以及为什么试图绕过它是一件坏事 (TM)!

参见 http://oreilly.com/catalog/jservlet/chapter/ch03.html#15894 :

Why not use a constructor instead? Well, in JDK 1.0 (for which servlets were originally written), constructors for dynamically loaded Java classes (such as servlets) couldn't accept arguments. So, in order to provide a new servlet any information about itself and its environment, a server had to call a servlet's init() method and pass along an object that implements the ServletConfig interface. Also, Java doesn't allow interfaces to declare constructors. This means that the javax.servlet.Servlet interface cannot declare a constructor that accepts a ServletConfig parameter. It has to declare another method, like init(). It's still possible, of course, for you to define constructors for your servlets, but in the constructor you don't have access to the ServletConfig object or the ability to throw a ServletException.

特别注意最后一句话:

[...] but in the constructor you don't have access to the ServletConfig object or the ability to throw a ServletException.

所以在 servlet 的构造函数中做任何事情都是:

  • 不切实际,
  • 但主要是相当危险!!

关于java - Servlet 中的构造函数和 finalize() 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17021689/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com