Issue
I want to ask about the difference between the following two implementations initializing a Servlet. (inline field initialization and init
method)
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 {
...
}
}
- Will the Servlet work normally when it is initialized in either way?
- Which initialization approach is preferred and what is the reason for that?
Thank you in advance!
Solution
I want to ask about the difference between the following two implementations initializing a Servlet.
The difference is in when the initialization performed.
In the first example, it is triggered by (for example) another class referring to one of the static
fields, or instantiating MyServlet
. This happens just once ... in the lifetime of that class.
In the second example, it is triggered by an explicit call to the init()
method. That is typically going to happen just once too, but it happens under the direct control of the framework.
Actually, there are some scenarios where init()
might be called more than once for a given servlet class. The method is actually called after each MyServlet
instance is created. So if your web configs reuse the same MyServlet
class for two distinct servlets, and the same classloader is used for both, then init()
would be called twice. Likewise, if the web container can shut down (i.e. destroy) all servlets and recreate them using the same classloader as before, then init()
would be called a second time. (But note that one class loaded by different classloaders is a different runtime class, each with its own set of static variables.)
Will the Servlet work normally when it is initialized in either way?
It depends on:
- whether something else might access one of those static variables before
init()
is called, - whether the construction of the
MyDao
instance depends on something else having already been initialized / configured, and - whether it would be harmful to call
init()
more than once.
Which initialization approach is preferred and what is the reason for that?
The first is simpler. Simpler is better ... if it does what you need.
However, this is not a "binary choice". You could initialize some of the statics one way, and some the other. For example:
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();
}
Note that static variables for (effective) constants should where possible be declared as final
to prevent accidental updates. Even if they are private
.
Also, consider if DAO
should really be an instance variable.
Answered By - Stephen C