是否可以声明自执行runnable?

时间:2011-12-13 15:39:34

标签: java constructor

喜欢这样吗?

abstract public class BaseTask extends Runnable {
    public BaseTask(ParamA aParam) {
         // do something with aParam
         StaticExecutorService.submit(this);
    }
}

public class AbcTask extends BaseTask {
    public ABC(ParamA aParam, ParamB bParam) {
        super(aParam);
    }
    @Override
    public void run() {

    }
}

然后可以通过执行

来创建类并排队等待执行
new AbcTask();
  1. 我不确定这是否可以,因为当ExecutorService决定执行AbcTask时,它仍在构建?

  2. 如果您出于任何原因不建议这样做,请说明并详细说明。

  3. 由于

4 个答案:

答案 0 :(得分:2)

这可能有用(至少,我对Java不太熟悉,不知道为什么它不会),但我不推荐它,因为它引入了太强大的耦合:AbcTask将与StaticExecutorService并且可以重复使用,而不是那么容易。这也将使AbcTask更难以测试和调试。

此外,您通过将提交文件折叠到执行程序中来“重载”对象构造的含义。如果您以后决定要在构建它们并提交它们之间对AbcTask个对象做些什么,该怎么办?

答案 1 :(得分:1)

在构造函数完成之前,我们不应该使用this

对象在完成它的c'tor后完全实例化。因此,StaticExecutorService内传递的对象可能无法完全创建,可能无法使用。

我不知道规范是否支持我的上述陈述。但我感觉如此。

因此,acc。对我来说应该避免。

答案 2 :(得分:1)

  1. 紧密耦合
  2. 在Effective Java中,Joshua Bloch解释了为什么从构造函数调用protected / public方法不是一个好习惯。参见第2版,CH-4:构造函数不得调用可覆盖的方法,直接间接

    StaticExecutorService.submit(this);
    

    上面的行将从构造函数中调用公共方法run,这是不期望的。


  3. 书中的解释:构造函数不得调用可覆盖的方法,直接间接

      

    如果违反此规则,将导致程序失败。超类构造函数运行   在子类构造函数之前,所以子类中的重写方法将得到   在子类构造函数运行之前调用。如果重写方法取决于   在子类构造函数执行的任何初始化上,该方法都不会   表现得像预期的那样。

答案 3 :(得分:0)

在您的示例中,它可能会工作但是,因为对super()的调用必须是BaseTask子类中的第一个,这意味着构造函数不会是能够在提交任务之前执行任何操作。

从您的示例中,无法使用第二个参数,因为在将任务分配给属性之前将提交任务。

如果我们考虑以下代码:

public class MyTask extends BaseTask {
    public ABC(ParamA aParam, String name) {
        super(aParam);
        this.name = name == null ? "Default Value" : name;
    }
    @Override
    public void run() {
         System.out.println("Name length: "+ name.length());
    }
}

由于run()可以在分配this.name之前调用,System.out行可以NullPointerException

结尾