question concerning downcast

J

jimjim

hello guys,

Curiosity made me take a look at the tomcat 's implementation of the servlet
API.

The HttpServlet class, which can be subclassed by http servlets, contains
the "service" method that is invoked by the servlet container in order to
pass a web request to a particular servlet. The method accepts a
ServletRequest and ServletResponse object as arguments, and downcasts them
to HttpServletRequest and HttpServletResponse respectively and then calls a
"service" method implemented by the same class:
public void service(ServletRequest req, ServletResponse res) throws
ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) { throw new ServletException("non-HTTP
request or response"); }
service(request, response);
}
}

How is it possible to do so, as the ServletRequest interface is more generic
than the HttpServletRequest (they have a hereditary relationship
HttpServletRequest== extends ServletRequest)?

TIA
 
J

Joona I Palaste

jimjim said:
hello guys,
Curiosity made me take a look at the tomcat 's implementation of the servlet
API.
The HttpServlet class, which can be subclassed by http servlets, contains
the "service" method that is invoked by the servlet container in order to
pass a web request to a particular servlet. The method accepts a
ServletRequest and ServletResponse object as arguments, and downcasts them
to HttpServletRequest and HttpServletResponse respectively and then calls a
"service" method implemented by the same class:
public void service(ServletRequest req, ServletResponse res) throws
ServletException, IOException
{
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) { throw new ServletException("non-HTTP
request or response"); }
service(request, response);
}
}
How is it possible to do so, as the ServletRequest interface is more generic
than the HttpServletRequest (they have a hereditary relationship
HttpServletRequest== extends ServletRequest)?

This is a basic fact of Java's implementation of polymorphism.
A downcast is not only a compile-time operation. A downcast is a promise
to the compiler, that at run-time, the object being downcast will be of
the type it's downcast to. If it isn't, you get a run-time error:
specifically a java.lang.ClassCastException.
You can only downcast an object reference value to a type that is
actually a subtype of its current type: if it's a class, a subclass of
it, or if it's an interface, a subinterface of it or a class
implementing the interface. If it's not a subtype, you get a
compile-time error.
In practice, what is happening here is that Tomcat is sure that what
gets passed into the service() method is really an HttpServletRequest
and not just a ServletRequest. An HttpServletRequest can be handled as
either interface, but a ServletRequest that isn't an HttpServletRequest
can't be handled as one.
All this downcasting might break some computer science theorists's idea
of pure OO, but it's what Java has decided to go with.
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
This is a basic fact of Java's implementation of polymorphism.
A downcast is not only a compile-time operation. A downcast is a
promise to the compiler, that at run-time, the object being downcast
will be of the type it's downcast to. If it isn't, you get a run-time
error: specifically a java.lang.ClassCastException.
You can only downcast an object reference value to a type that is
actually a subtype of its current type: if it's a class, a subclass of
it, or if it's an interface, a subinterface of it or a class
implementing the interface. If it's not a subtype, you get a
compile-time error.
In practice, what is happening here is that Tomcat is sure that what
gets passed into the service() method is really an HttpServletRequest
and not just a ServletRequest. An HttpServletRequest can be handled as
either interface, but a ServletRequest that isn't an
HttpServletRequest can't be handled as one.
All this downcasting might break some computer science theorists's
idea of pure OO, but it's what Java has decided to go with.

You can see "is downcasting bad" threads in comp.object from time to time.
Most computer science theorists see that downcasting is /not/ bad, but just
needs to be used with caution because overuse can easily result in horrible
design.
 
J

jimjim

In practice, what is happening here is that Tomcat is sure that what
gets passed into the service() method is really an HttpServletRequest
and not just a ServletRequest. An HttpServletRequest can be handled as
either interface, but a ServletRequest that isn't an HttpServletRequest
can't be handled as one.

hmm, i made the mistake not to look at the servlet spec, which states that
"The servlet container creates an HttpServletRequest object and passes it as
an argument to the servlet's service methods (doGet, doPost, etc)". So
indeed the servlet container creates an HttpServletRequest object. I thought
that the HttpServletRequest was not part of the servlet API, but a
proprietary implementation of tomcat for providing a faster development
track for Http servlets to the programmers.


Thx you both for the input.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top