Servlet:init() 方法与内联字段初始化
Servlet: init() method vs inline field initialization
想问一下下面两种初始化Servlet的实现方式的区别。 (内联字段初始化和 init
方法)
public class MyServlet extends HttpServlet {
private static String FILE_PATH = "/.../.../.../";
private static String DATE = "date";
private static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO = new MyDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
VS.
public class MyServlet extends HttpServlet {
private static String FILE_PATH;
private static String DATE;
private static DateTimeFormatter FORMAT;
private static MyDao DAO;
@Override
public void init(){
FILE_PATH = "/.../.../.../";
String DATE = "date";
FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
DAO = new MyDao();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
- 无论哪种方式初始化Servlet都能正常工作吗?
- 首选哪种初始化方法,原因是什么?
提前致谢!
I want to ask about the difference between the following two implementations initializing a Servlet.
区别在于何时执行初始化。
在第一个示例中,它由(例如)另一个 class 引用 static
字段之一或实例化 MyServlet
触发。这种情况只发生一次......在 class.
的生命周期中
在第二个示例中,它是由对 init()
方法的显式调用触发的。那就是 通常 也只会发生一次,但它是在框架的直接控制下发生的。
实际上,在某些情况下,对于给定的 servlet class,可能会多次调用 init()
。该方法实际上是在每个 MyServlet
实例 创建后调用的。因此,如果您的 Web 配置对两个不同的 servlet 重用相同的 MyServlet
class,并且对两者使用相同的 classloader,那么 init()
将被调用两次。同样,如果 Web 容器可以关闭(即销毁)所有 servlet 并使用与以前相同的 classloader 重新创建它们,那么 init()
将被第二次调用。 (但请注意,由不同的 classloader 加载的 class 是不同的运行时 class,每个运行时都有自己的一组静态变量。)
Will the Servlet work normally when it is initialized in either way?
取决于:
- 在调用
init()
之前是否有其他东西可以访问这些静态变量之一,
MyDao
实例的构造是否依赖于已经初始化/配置的其他东西,并且
- 多次调用
init()
是否有害。
Which initialization approach is preferred and what is the reason for that?
第一种比较简单。越简单越好...如果它满足您的需要。
然而,这不是“二选一”。您可以用一种方式初始化一些静态参数,然后用另一种方式初始化一些静态参数。例如:
public class MyServlet extends HttpServlet {
private static final String FILE_PATH = "/.../.../.../";
private static final String DATE = "date";
private static final DateTimeFormatter FORMAT =
DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO;
@Override
public void init() {
MyServlet.DAO = new MyDao();
}
请注意,(有效)常量的静态变量应尽可能声明为 final
以防止意外更新。即使他们是 private
.
此外,考虑 DAO
是否真的应该是一个实例变量。
想问一下下面两种初始化Servlet的实现方式的区别。 (内联字段初始化和 init
方法)
public class MyServlet extends HttpServlet {
private static String FILE_PATH = "/.../.../.../";
private static String DATE = "date";
private static DateTimeFormatter FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO = new MyDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
VS.
public class MyServlet extends HttpServlet {
private static String FILE_PATH;
private static String DATE;
private static DateTimeFormatter FORMAT;
private static MyDao DAO;
@Override
public void init(){
FILE_PATH = "/.../.../.../";
String DATE = "date";
FORMAT = DateTimeFormatter.ofPattern("yyyyMMdd");
DAO = new MyDao();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
...
}
}
- 无论哪种方式初始化Servlet都能正常工作吗?
- 首选哪种初始化方法,原因是什么?
提前致谢!
I want to ask about the difference between the following two implementations initializing a Servlet.
区别在于何时执行初始化。
在第一个示例中,它由(例如)另一个 class 引用 static
字段之一或实例化 MyServlet
触发。这种情况只发生一次......在 class.
在第二个示例中,它是由对 init()
方法的显式调用触发的。那就是 通常 也只会发生一次,但它是在框架的直接控制下发生的。
实际上,在某些情况下,对于给定的 servlet class,可能会多次调用 init()
。该方法实际上是在每个 MyServlet
实例 创建后调用的。因此,如果您的 Web 配置对两个不同的 servlet 重用相同的 MyServlet
class,并且对两者使用相同的 classloader,那么 init()
将被调用两次。同样,如果 Web 容器可以关闭(即销毁)所有 servlet 并使用与以前相同的 classloader 重新创建它们,那么 init()
将被第二次调用。 (但请注意,由不同的 classloader 加载的 class 是不同的运行时 class,每个运行时都有自己的一组静态变量。)
Will the Servlet work normally when it is initialized in either way?
取决于:
- 在调用
init()
之前是否有其他东西可以访问这些静态变量之一, MyDao
实例的构造是否依赖于已经初始化/配置的其他东西,并且- 多次调用
init()
是否有害。
Which initialization approach is preferred and what is the reason for that?
第一种比较简单。越简单越好...如果它满足您的需要。
然而,这不是“二选一”。您可以用一种方式初始化一些静态参数,然后用另一种方式初始化一些静态参数。例如:
public class MyServlet extends HttpServlet {
private static final String FILE_PATH = "/.../.../.../";
private static final String DATE = "date";
private static final DateTimeFormatter FORMAT =
DateTimeFormatter.ofPattern("yyyyMMdd");
private static MyDao DAO;
@Override
public void init() {
MyServlet.DAO = new MyDao();
}
请注意,(有效)常量的静态变量应尽可能声明为 final
以防止意外更新。即使他们是 private
.
此外,考虑 DAO
是否真的应该是一个实例变量。