Java constructors for side-effects only
I have a Java instance class, "ResultMaker" that exists for side-effects only (sending an email) and the object is never subsequently used. (Of course this could be re-written so that ResultMaker is a static class, but when I add "flesh" to the class, adding methods and making multiple instances, I think I would eventually want to have a reference to the object, so my justification for declaring ResultMaker as an instance class at this stage is that the code is not finished yet.)
In order to clean up a Java warning that r
was unused (see the short example code), I removed the assignment to variable r
(see code) so I was left with only 开发者_运维问答a new ResultMaker(ans)
. The side-effect stopped happening with the code change so I guess instantiation of ResultMaker no longer happens. Is this deserving of a compiler warning (that there will be no instantiation) or is this a well-known aspect of Java?
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException
{
Thing tt = new Thing();
String answer = tt.DoSomething();
ResultMaker r = new ResultMaker(answer);
resp.getWriter().println(answer);
}
I suspect you aren't really seeing what you think you're seeing. I very much doubt that the constructor call was removed. If you could provide a short but complete program which demonstrates the problem, that would help - but I suspect you'll find that it was some other change - possibly to how you observe the side-effect - that happened.
I would strongly encourage you to make this a static method which describes the side-effects you're expecting though - a constructor call which doesn't actually use the result is odd, and I wouldn't be surprised to see a maintainer remove the call expecting it to be a no-op. The purpose of a constructor ought to be to construct an object, not for side-effects.
EDIT: If your code is actually like that, then the first thing I'd do is change these empty exception blocks:
catch (UnsupportedEncodingException e)
{
}
catch (AddressException e)
{
}
catch (MessagingException e)
{
}
At the very least these should log what's gone wrong.
For investigative purposes I'd also add logging before and after the constructor call, and within the constructor. That should help show how the execution is actually flowing.
Since the action of sending an email is pretty much stateless, you can add a method to the ResultMaker
class (MailSender
?), something along the lines of r.sendMail(content)
. If you are using Spring or Guice, you can create a singleton and inject it throughout the application. A poor man's solution would be put a ResultMaker
instance in the ServletContext
when the application starts and re-use the same instance for all requests.
精彩评论