仅用于副作用的Java构造函数

仅用于副作用的Java构造函数,java,Java,我有一个Java实例类“ResultMaker”,它的存在只是为了产生副作用(发送电子邮件),并且以后再也不会使用该对象。(当然,这可以重新编写,使ResultMaker成为一个静态类,但当我向类中添加“肉体”,添加方法并创建多个实例时,我想我最终会希望有一个对对象的引用,因此我在这个阶段将ResultMaker声明为实例类的理由是代码尚未完成。) 为了清除r未使用的Java警告(请参阅简短的示例代码),我删除了变量r(请参阅代码)的赋值,因此只剩下新的ResultMaker(ans)。随着代码

我有一个Java实例类“ResultMaker”,它的存在只是为了产生副作用(发送电子邮件),并且以后再也不会使用该对象。(当然,这可以重新编写,使ResultMaker成为一个静态类,但当我向类中添加“肉体”,添加方法并创建多个实例时,我想我最终会希望有一个对对象的引用,因此我在这个阶段将ResultMaker声明为实例类的理由是代码尚未完成。)

为了清除
r
未使用的Java警告(请参阅简短的示例代码),我删除了变量
r
(请参阅代码)的赋值,因此只剩下
新的ResultMaker(ans)
。随着代码的更改,副作用停止了,所以我猜ResultMaker的实例化不再发生。这是否值得编译器警告(不会有实例化),或者这是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);
    }

我怀疑你没有真正看到你认为你看到的东西。我非常怀疑构造函数调用是否被删除。如果你能提供一个简短但完整的程序来演示这个问题,那会有所帮助——但我怀疑你会发现,这是其他一些变化——可能是你观察副作用的方式——发生了

我强烈建议你把它变成一个静态方法,描述你所期望的副作用——一个没有实际使用结果的构造函数调用是很奇怪的,如果一个维护人员删除了这个调用,并期望它是一个不可操作的调用,我也不会感到惊讶。构造函数的目的应该是构造一个对象,没有副作用

编辑:如果您的代码实际上是这样的,那么我要做的第一件事就是更改这些空异常块:

catch (UnsupportedEncodingException e)
{
}
catch (AddressException e) 
{
} 
catch (MessagingException e) 
{
}
至少这些应该记录出什么地方出了问题


出于调查目的,我还将在构造函数调用之前和之后以及构造函数内部添加日志记录。这应该有助于显示执行的实际流程。

由于发送电子邮件的操作几乎是无状态的,您可以向
ResultMaker
类(
mailssender
?)添加一个方法,类似于
r.sendMail(content)
。如果您使用的是Spring或Guice,那么可以创建一个单例并将其注入整个应用程序。穷人的解决方案是在应用程序启动时将一个
ResultMaker
实例放在
ServletContext
中,并对所有请求重复使用同一实例。

+1-但如果通过ServletContext共享/重用
ResultMaker
实例,则需要1)使其线程安全,斯蒂芬:的确如此,但正如前面提到的:1)发送邮件几乎总是无状态的,如果不是这样,那么它就不应该像OP使用它的方式那样使用;2)很好;我要么将邮件请求发布到持久作业队列,要么简单地使用ExecutorService来确保请求处理线程不会阻塞。:-)乔恩,你是对的。纯粹用于副作用的构造函数确实有效,但GAE的不确定性导致我将问题归因于涉及构造函数的代码更改。为了完整性:不确定性与GAE的Queue.purge调用有关(未显示)。它异步运行,需要不确定的时间。