如何将TimerTask与lambdas一起使用?

ski*_*iwi 20 java lambda abstract-class timertask java-8

正如您所知,您可以在Java 8中使用lambdas,例如替换匿名方法.

这里可以看到Java 7与Java 8的一个例子:

Runnable runnable = new Runnable() {
    @Override
    public void run() {
        checkDirectory();
    }
};
Run Code Online (Sandbox Code Playgroud)

在Java 8中可以表示为以下两种方式:

Runnable runnable = () -> checkDirectory();
Run Code Online (Sandbox Code Playgroud)

要么

Runnable runnable = this::checkDirectory;
Run Code Online (Sandbox Code Playgroud)

这是因为它Runnable是一个功能接口,只有一个(抽象)公共非默认方法.

但是......因为TimerTask我们有以下内容:

TimerTask timerTask = new TimerTask() {
    @Override
    public void run() {
        checkDirectory();
    }
};
Run Code Online (Sandbox Code Playgroud)

看起来很熟悉吧?
使用lambda表达式不起作用,因为它TimerTask是一个抽象类,即使它只有一个抽象的公共非默认方法,它也不是一个接口,因此也没有功能接口.
它也没有重构为具有默认实现的接口,因为它带有状态,因此无法完成.

所以我的问题:构建时有没有办法使用lambdas TimerTask

我想要的是以下内容:

Timer timer = new Timer();
timer.schedule(this::checkDirectory, 0, 1 * 1000);
Run Code Online (Sandbox Code Playgroud)

而不是一些丑陋的匿名内部类,有没有办法让它更好?

Mar*_*nik 12

首先注意到这Timer是一个过时的API,但是对你的问题很有趣,你可以在它周围写一个小包装器,它会调整schedule方法来接受一个Runnable,而在内部你会把它Runnable变成一个TimerTask.那么你将拥有schedule接受lambda的方法.

public class MyTimer {
  private final Timer t = new Timer();

  public TimerTask schedule(final Runnable r, long delay) {
     final TimerTask task = new TimerTask() { public void run() { r.run(); }};
     t.schedule(task, delay);
     return task;
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 从技术上讲,你的答案是正确的,但我个人会使用`ScheduledExecutorService`而不是`TimerTask`. (9认同)
  • 那么当前的API是什么? (2认同)