java8: 请问这种写法,为什么可以作为线程对象参数传递?

// Java8可以把方法作为参数传递,但是 这个endOfWashing方法并没有返回线程对象啊?为什么可以编译通过呢?
代码如下,请看wash方法 下面那个参数this::endOfWashing :
  private static final Logger LOGGER = LoggerFactory.getLogger(WashingMachine.class);
  private final DelayProvider delayProvider;
  private WashingMachineState washingMachineState;

   public WashingMachine() {
    this((interval, timeUnit, task) -> {
      try {
        Thread.sleep(timeUnit.toMillis(interval));
      } catch (InterruptedException ie) {
        ie.printStackTrace();
      }
      task.run();
    });
  }

  /**
   * Creates a new instance of WashingMachine using provided delayProvider. This constructor is used only for
   * unit testing purposes.
   */
  public WashingMachine(DelayProvider delayProvider) {
    this.delayProvider = delayProvider;
    this.washingMachineState = WashingMachineState.ENABLED;
  }
  public void wash() {
    synchronized (this) {
      LOGGER.info("{}: Actual machine state: {}", Thread.currentThread().getName(), getWashingMachineState());
      if (washingMachineState == WashingMachineState.WASHING) {
        LOGGER.error("ERROR: Cannot wash if the machine has been already washing!");
        return;
      }
      washingMachineState = WashingMachineState.WASHING;
    }
    LOGGER.info("{}: Doing the washing", Thread.currentThread().getName());

    this.delayProvider.executeAfterDelay(50, TimeUnit.MILLISECONDS, this::endOfWashing);
  }
  /**
   * Method responsible of ending the washing
   * by changing machine state
   */
  public synchronized void endOfWashing() {
    washingMachineState = WashingMachineState.ENABLED;
    LOGGER.info("{}: Washing completed.", Thread.currentThread().getId());
  }
/**
 * An interface to simulate delay while executing some work.
 */
public interface DelayProvider {
  void executeAfterDelay(long interval, TimeUnit timeUnit, Runnable task);
}
阅读 3.5k
2 个回答

this::endOfWashing这个写法是java8的新语法。它不是调用endOfWashing,调用endOfWashing的语法是this.endOfWashing。

它不是把endOfWashing的返回值传给executeAfterDelay,而是把endOfWashing作为一个lambda表达式传给executeAfterDelay,类似c#里面的委托和javascript的回调函数。executeAfterDelay的内部会在某个时机调用作为回调函数的endOfWashing方法。

this::endOfWashing 等同于 () -> endOfWashing()
现在还有疑问吗?

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题