4

Why do we have to override init() method in Servlets while we can do the initialization in the constructor and have web container call the constructor passing ServletConfig reference to servlet while calling constructor?

Ofcourse container has to use reflection for this but container has to use reflection anyway to call a simple no-arg constructor

Reddy
  • 8,737
  • 11
  • 55
  • 73
  • [Lot of dupes here](http://www.google.com/search?hl=&q=servlet+constructor+init+site%3Astackoverflow.com) – BalusC May 27 '10 at 14:33

5 Answers5

15

Since a constructor can not be part of an interface, it can not be "formally" specified within the Servlet API, unlike normal methods. Moreover, since Java has no destructors, a destroy method is needed anyway, so it defining the corresponding init method makes the API more consistent and easier to use.

Using reflection to detect/verify constructor parameters would just unnecessarily complicate things, and I don't see any added value.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 1
    Well, reflection is used anyway, and the added value would be that you can make your servlets immutable. There are many examples of classes which do initialization in the constructor but which have a corresponding close method; pretty much every single stream class works this way. – gustafc May 27 '10 at 11:42
  • @gustafc, since you are not supposed to store (nonstatic) data in your servlets anyway, immutability doesn't really make a difference. Stream classes are a good example; however note that these are concrete classes, not interfaces. – Péter Török May 27 '10 at 12:00
  • There are very good reasons for having (immutable) non-static state in servlets. The whole point of `ServletConfig` is that you can instantiate the same servlet several times and have it do (slightly) different things. – gustafc May 27 '10 at 12:08
  • @Peter, though unrelated don't we have a finalize() method which can be used as a destructor? – Reddy May 27 '10 at 12:13
  • @gustafc, sorry I didn't understand what is immutability... can you please explain? – Reddy May 27 '10 at 12:13
  • @Reddy, `finalize()` is not a destructor and practically should not be used. See [What is the purpose of Finalization in java?](http://stackoverflow.com/questions/2450580/what-is-the-purpose-of-finalization-in-java), and for further details, [this article](http://www.codeguru.com/java/tij/tij0051.shtml). – Péter Török May 27 '10 at 12:39
  • @gustafc, note that `ServletConfig` does not mandate using nonstatic data members. – Péter Török May 27 '10 at 12:41
  • @Reddy, immutability means that you can't change an object after it has been initialized (in Java, that means after the constructor has finished). It's genereally considered a Good Thing 'cause it makes it a lot easier to reason about your code. – gustafc May 27 '10 at 13:26
  • @Péter Török: If you put stuff into static fields, what happens then when you have the same servlet class mapped to several different servlets with different configurations? (Answer: Whatever servlet was loaded last overwrites the values set by the previously loaded servlets.) – gustafc May 27 '10 at 13:28
  • @gustafc, fair enough, my comment was poorly worded - just skip "nonstatic". – Péter Török May 27 '10 at 13:43
5

Servlet object has a well-defined life cycle where creation and initialization steps are distinct. Usually you don't want to do heavy and unreliable work in constructors, e.g. getting DB connection pool or initializing cache. You have a chance to do it after a Servlet object is successfully created.

Also, here http://oreilly.com/catalog/jservlet/chapter/ch03.html is a historical reason:

The init() method is typically used to perform servlet initialization--creating or loading objects that are used by the servlet in the handling of its requests. 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.

leopoldkot
  • 171
  • 6
2

One reason is that you don't have access to the ServletConfig object in the constructor. The ServletConfig object is created after the constructor is called and before init() is called. So, you cannot access servlet init parameters in the constructor.

Michael
  • 34,873
  • 17
  • 75
  • 109
1

Servlet implementation classes can have constructor but they should be using init() method to initialize Servlet because of two reasons, first you cannot declare constructors on interface in Java, which means you cannot enforce this requirement to any class which implements Servlet interface and second, Servlet require ServletConfig object for initialization which is created by container as it also has reference of ServletContext object, which is also created by container.

Servlet is an interface defined in javax.servlet package and HttpServlet is a class and like any other class in Java they can have constructor, but you cannot declare constructor inside interface in Java. If you don't provide an explicit constructor than compiler will add a default no argument constructor in any Servlet implementation class. Another reason that you should not initialize Servlet using constructor because Servlets are not directly instantiated by Java code, instead container create there instance and keep them in pool. Since containers from web servers like Tomcat and Jetty uses Java Reflection for creating instance of Servlet, presence of no argument constructor is must. So, by any chance if you provide a parametric constructor and forget to write a no argument constructor, web container will not be able to create instance of your Servlet, since there is no default constructor. Remember Java compiler doesn't add default no argument constructor, if there is a parametric constructor present in class. That's why it's not advised to provide constructor in Servlet class.

Balamurugan
  • 116
  • 8
0

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. see:doc

In detail,If you want to dynamically load a Java class, you should use the following method:

Class<MyClass> clazz = MyClass.class;
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class);
MyClass instance = ctor.newInstance("foo");

But, the method which returns a Constructor object in the Class class has been written since jdk1.1. In jdk1.0, you can only use the following parameterless method:

Object newObject = Class.forName(strFullyQualifiedClassName).newInstance();
spongecaptain
  • 121
  • 1
  • 11