I have two options in a Servlet regarding the initialization of a variable that I don’t want to change over the lifetime of the @Singleton Servlet, we’ll call it:
Field a;
Field a will be used internally by the servlet only, there are no accessor methods, and for simplicity’s sake, Field a is something immutable, like a String.
Option 1 – Initialize the field inside a constructor utilizing information gained from dependency injection of the ServletContext, so that the field becomes:
private final Field a;
Option 2 – Set the variable in an overridden init(ServletConfig cfg) method utilizing information gained from the ServletConfig (and ServletContext) so that the field becomes:
private Field a;
Obviously, I would prefer to have the field final, but the field is private and has no accessor methods attached to it, so should I still try to make it final?
So, in summary, should a field be initialized in the constructor and made final, or initialized in the init method and left as non-final with no accessors?
Thank you.
In addition to documenting your intent clearly and making your code easier to understand and maintain, a
finalmodifier provides some important assurances in a multi-threaded application.While I’m not sure if it’s guaranteed by the Servlet specification, it seems that in practice, servlet engines should use some memory barrier that will ensure that the internal state of a new servlet instance is visible to all of the threads that will use it to process servlet requests. This is called “safe publication.”
However, in general, this is not the case. What you describe as “Option 2” is “effective immutability.” The object has a field that isn’t
final, but doesn’t allow modification of that field after construction or some initialization step. But, if other threads access this object without going through a memory barrier, they might not see the value assigned to that field by the initializing thread—even if this field was set in the object’s constructor!A value assigned during object construction to a
finalfield, however, is guaranteed to be visible to all other threads, even if the object itself is not “safely published.”